summaryrefslogtreecommitdiff
path: root/net-ftp/atftp/files
diff options
context:
space:
mode:
Diffstat (limited to 'net-ftp/atftp/files')
-rw-r--r--net-ftp/atftp/files/atftp-0.7.2-cve-2020-6097.patch92
-rw-r--r--net-ftp/atftp/files/atftp-0.7.2-fewer_seeks.patch38
2 files changed, 130 insertions, 0 deletions
diff --git a/net-ftp/atftp/files/atftp-0.7.2-cve-2020-6097.patch b/net-ftp/atftp/files/atftp-0.7.2-cve-2020-6097.patch
new file mode 100644
index 000000000000..5130d0086432
--- /dev/null
+++ b/net-ftp/atftp/files/atftp-0.7.2-cve-2020-6097.patch
@@ -0,0 +1,92 @@
+commit 96409ef3b9ca061f9527cfaafa778105cf15d994
+Author: Peter Kaestle <peter.kaestle@nokia.com>
+Date: Wed Oct 14 14:02:41 2020 +0200
+
+ Fix for DoS issue CVE-2020-6097
+
+ "sockaddr_print_addr" of tftpd can be triggered remotely to call
+ assert(), which will crash the tftpd daemon. See:
+ https://talosintelligence.com/vulnerability_reports/TALOS-2020-1029
+
+ "sockaddr_print_addr" originaly had two features:
+ 1) returning pointer to string of the incoming ip address
+ 2) checking whether ss_family of the connection is supported
+
+ To fix the issue, a separate function "sockaddr_family_supported" is
+ used to take care of 2) and "sockaddr_print_addr" returns an error
+ message string for unsupported cases when using 1) insert of calling
+ assert().
+
+diff --git a/tftp_def.c b/tftp_def.c
+index d457c2a..428a930 100644
+--- a/tftp_def.c
++++ b/tftp_def.c
+@@ -180,6 +180,15 @@ int Gethostbyname(char *addr, struct hostent *host)
+ return OK;
+ }
+
++int
++sockaddr_family_supported(const struct sockaddr_storage *ss)
++{
++ if (ss->ss_family == AF_INET || ss->ss_family == AF_INET6)
++ return 1;
++ else
++ return 0;
++}
++
+ char *
+ sockaddr_print_addr(const struct sockaddr_storage *ss, char *buf, size_t len)
+ {
+@@ -189,7 +198,7 @@ sockaddr_print_addr(const struct sockaddr_storage *ss, char *buf, size_t len)
+ else if (ss->ss_family == AF_INET6)
+ addr = &((const struct sockaddr_in6 *)ss)->sin6_addr;
+ else
+- assert(!"sockaddr_print: unsupported address family");
++ return "sockaddr_print: unsupported address family";
+ return (char *)inet_ntop(ss->ss_family, addr, buf, len);
+ }
+
+diff --git a/tftp_def.h b/tftp_def.h
+index 0841746..458e310 100644
+--- a/tftp_def.h
++++ b/tftp_def.h
+@@ -54,6 +54,7 @@ int print_eng(double value, char *string, int size, char *format);
+ inline char *Strncpy(char *to, const char *from, size_t size);
+ int Gethostbyname(char *addr, struct hostent *host);
+
++int sockaddr_family_supported(const struct sockaddr_storage *ss);
+ char *sockaddr_print_addr(const struct sockaddr_storage *, char *, size_t);
+ #define SOCKADDR_PRINT_ADDR_LEN INET6_ADDRSTRLEN
+ uint16_t sockaddr_get_port(const struct sockaddr_storage *);
+diff --git a/tftpd.c b/tftpd.c
+index 0b6f6a5..a7561a5 100644
+--- a/tftpd.c
++++ b/tftpd.c
+@@ -644,6 +644,11 @@ void *tftpd_receive_request(void *arg)
+ }
+
+ #ifdef HAVE_WRAP
++ if (!abort && !sockaddr_family_supported(&data->client_info->client))
++ {
++ logger(LOG_ERR, "Connection from unsupported network address family refused");
++ abort = 1;
++ }
+ if (!abort)
+ {
+ /* Verify the client has access. We don't look for the name but
+diff --git a/tftpd_mtftp.c b/tftpd_mtftp.c
+index d420d10..0032905 100644
+--- a/tftpd_mtftp.c
++++ b/tftpd_mtftp.c
+@@ -393,6 +393,11 @@ void *tftpd_mtftp_server(void *arg)
+ &data_size, data->data_buffer);
+
+ #ifdef HAVE_WRAP
++ if (!sockaddr_family_supported(&sa))
++ {
++ logger(LOG_ERR, "mtftp: Connection from unsupported network address family refused");
++ continue;
++ }
+ /* Verify the client has access. We don't look for the name but
+ rely only on the IP address for that. */
+ sockaddr_print_addr(&sa, addr_str, sizeof(addr_str));
diff --git a/net-ftp/atftp/files/atftp-0.7.2-fewer_seeks.patch b/net-ftp/atftp/files/atftp-0.7.2-fewer_seeks.patch
new file mode 100644
index 000000000000..78926b94b9f7
--- /dev/null
+++ b/net-ftp/atftp/files/atftp-0.7.2-fewer_seeks.patch
@@ -0,0 +1,38 @@
+<F28>diff -U8 atftp-0.7.2/tftp_io.c /var/tmp/portage/net-ftp/atftp-0.7.2-r1/work/atftp-0.7.2/tftp_io.c
+--- atftp-0.7.2/tftp_io.c 2019-04-14 17:38:55.000000000 -0500
++++ /var/tmp/portage/net-ftp/atftp-0.7.2-r1/work/atftp-0.7.2/tftp_io.c 2020-03-16 12:55:22.371820662 -0500
+@@ -439,26 +439,32 @@
+ }
+
+ /*
+ * Write to file and do netascii conversion if needed
+ */
+ int tftp_file_write(FILE *fp, char *data_buffer, int data_buffer_size, long block_number, int data_size,
+ int convert, long *prev_block_number, int *temp)
+ {
++ static long filepos;
+ int bytes_written;
+ int c;
+ char prevchar = *temp;
+
+ if (!convert)
+ {
+ /* Simple case, just seek and write */
+- if (fseek(fp, (block_number - 1) * data_buffer_size, SEEK_SET) != 0)
+- return 0;
++ long position = (block_number - 1)*data_buffer_size;
++ if (position != filepos)
++ if (fseek(fp, position, SEEK_SET) != 0)
++ return 0;
++ else
++ filepos = position;
+ bytes_written = fwrite(data_buffer, 1, data_size, fp);
++ filepos += bytes_written;
+ }
+ else if (block_number != *prev_block_number)
+ {
+ /*
+ * Same principle than for reading, but simpler since when client
+ * send same block twice there is no need to rewrite it to the
+ * file
+ */