Hello community,

here is the log from the commit of package tftp for openSUSE:11.3
checked in at Fri Jun 24 16:13:23 CEST 2011.



--------
--- old-versions/11.3/all/tftp/tftp.changes     2010-07-01 14:12:03.000000000 
+0200
+++ 11.3/tftp/tftp.changes      2011-06-24 09:17:01.000000000 +0200
@@ -1,0 +2,6 @@
+Wed Jun 22 13:24:51 UTC 2011 - [email protected]
+
+- fix buffer overflow (bnc#699714)
+  - tftp-hpa-CVE-2011-2199.patch
+
+-------------------------------------------------------------------

Package does not exist at destination yet. Using Fallback 
old-versions/11.3/all/tftp
Destination is old-versions/11.3/UPDATES/all/tftp
calling whatdependson for 11.3-i586


New:
----
  tftp-hpa-CVE-2011-2199.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tftp.spec ++++++
--- /var/tmp/diff_new_pack.GZFZNV/_old  2011-06-24 16:12:07.000000000 +0200
+++ /var/tmp/diff_new_pack.GZFZNV/_new  2011-06-24 16:12:07.000000000 +0200
@@ -1,7 +1,7 @@
 #
-# spec file for package tftp (Version 0.48)
+# spec file for package tftp
 #
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -29,7 +29,7 @@
 Requires:       inet-daemon netcfg
 AutoReqProv:    on
 Version:        0.48
-Release:        107
+Release:        108.<RELEASE2>
 Summary:        Trivial File Transfer Protocol (TFTP)
 Source:         tftp-hpa-git-%{version}.tar.bz2
 Source1:        tftp.xinetd
@@ -38,6 +38,7 @@
 Patch2:         tftp-hpa-0.43_readline.diff
 Patch3:         tftp-hpa-0.46_libedit.patch
 Patch4:         tftp-hpa-0.49-fortify-strcpy-crash.patch
+Patch5:         tftp-hpa-CVE-2011-2199.patch
 Patch42:        tftp-hpa-0.43_old-autoconf.diff
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -59,6 +60,7 @@
 %patch2
 %patch3
 %patch4 -p1
+%patch5 -p1
 %if 0%{?suse_version} < 1030
 %patch42
 %endif

++++++ tftp-hpa-CVE-2011-2199.patch ++++++
>From f3035c45bc50bb5cac87ca01e7ef6a12485184f8 Mon Sep 17 00:00:00 2001
From: H. Peter Anvin <[email protected]>
Date: Fri, 10 Jun 2011 11:47:02 -0700
Subject: [PATCH] tftpd: simplify option parsing

Simplify the option parsing to make use of the fact that all the
options we support are integer options.  This fixes a buffer overflow
in the utimeout option.

Reported-by: Timo Warns <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Signed-off-by: Petr Uzel <[email protected]>
---
 tftpd/tftpd.c |  154 +++++++++++++++++++++++++++------------------------------
 1 files changed, 73 insertions(+), 81 deletions(-)

Index: tftp-hpa-git-0.48/tftpd/tftpd.c
===================================================================
--- tftp-hpa-git-0.48.orig/tftpd/tftpd.c
+++ tftp-hpa-git-0.48/tftpd/tftpd.c
@@ -112,17 +112,17 @@ static struct rule *rewrite_rules = NULL
 int tftp(struct tftphdr *, int);
 static void nak(int, const char *);
 static void timer(int);
-static void do_opt(char *, char *, char **);
+static void do_opt(const char *, const char *, char **);
 
-static int set_blksize(char *, char **);
-static int set_blksize2(char *, char **);
-static int set_tsize(char *, char **);
-static int set_timeout(char *, char **);
-static int set_utimeout(char *, char **);
+static int set_blksize(uintmax_t *);
+static int set_blksize2(uintmax_t *);
+static int set_tsize(uintmax_t *);
+static int set_timeout(uintmax_t *);
+static int set_utimeout(uintmax_t *);
 
 struct options {
     const char *o_opt;
-    int (*o_fnc) (char *, char **);
+    int (*o_fnc) (uintmax_t *);
 } options[] = {
     {"blksize",  set_blksize},
     {"blksize2", set_blksize2},
@@ -1099,48 +1099,38 @@ static int blksize_set;
 /*
  * Set a non-standard block size (c.f. RFC2348)
  */
-static int set_blksize(char *val, char **ret)
+static int set_blksize(uintmax_t *vp)
 {
-    static char b_ret[6];
-    unsigned int sz;
-    char *vend;
-
-    sz = (unsigned int)strtoul(val, &vend, 10);
+    uintmax_t sz = *vp;
 
-    if (blksize_set || *vend)
+    if (blksize_set)
         return 0;
 
     if (sz < 8)
-        return (0);
+        return 0;
     else if (sz > max_blksize)
         sz = max_blksize;
 
-    segsize = sz;
-    sprintf(*ret = b_ret, "%u", sz);
-
+    *vp = segsize = sz;
     blksize_set = 1;
-
-    return (1);
+    return 1;
 }
 
 /*
  * Set a power-of-two block size (nonstandard)
  */
-static int set_blksize2(char *val, char **ret)
+static int set_blksize2(uintmax_t *vp)
 {
-    static char b_ret[6];
-    unsigned int sz;
-    char *vend;
+    uintmax_t sz = *vp;
 
-    sz = (unsigned int)strtoul(val, &vend, 10);
-
-    if (blksize_set || *vend)
+    if (blksize_set)
         return 0;
 
     if (sz < 8)
         return (0);
     else if (sz > max_blksize)
         sz = max_blksize;
+    else
 
     /* Convert to a power of two */
     if (sz & (sz - 1)) {
@@ -1151,12 +1141,10 @@ static int set_blksize2(char *val, char
         sz = sz1;
     }
 
-    segsize = sz;
-    sprintf(*ret = b_ret, "%u", sz);
-
+    *vp = segsize = sz;
     blksize_set = 1;
 
-    return (1);
+    return 1;
 }
 
 /*
@@ -1164,22 +1152,18 @@ static int set_blksize2(char *val, char
  * For netascii mode, we don't know the size ahead of time;
  * so reject the option.
  */
-static int set_tsize(char *val, char **ret)
+static int set_tsize(uintmax_t *vp)
 {
-    static char b_ret[sizeof(uintmax_t) * CHAR_BIT / 3 + 2];
-    uintmax_t sz;
-    char *vend;
-
-    sz = strtoumax(val, &vend, 10);
+    uintmax_t sz = *vp;
 
-    if (!tsize_ok || *vend)
+    if (!tsize_ok)
         return 0;
 
     if (sz == 0)
-        sz = (uintmax_t) tsize;
+        sz = tsize;
 
-    sprintf(*ret = b_ret, "%" PRIuMAX, sz);
-    return (1);
+    *vp = sz;
+    return 1;
 }
 
 /*
@@ -1187,74 +1171,86 @@ static int set_tsize(char *val, char **r
  * to be the (default) retransmission timeout, but being an
  * integer in seconds it seems a bit limited.
  */
-static int set_timeout(char *val, char **ret)
+static int set_timeout(uintmax_t *vp)
 {
-    static char b_ret[4];
-    unsigned long to;
-    char *vend;
+    uintmax_t to = *vp;
 
-    to = strtoul(val, &vend, 10);
-
-    if (to < 1 || to > 255 || *vend)
+    if (to < 1 || to > 255)
         return 0;
 
     rexmtval = timeout = to * 1000000UL;
     maxtimeout = rexmtval * TIMEOUT_LIMIT;
 
-    sprintf(*ret = b_ret, "%lu", to);
-    return (1);
+    return 1;
 }
 
 /* Similar, but in microseconds.  We allow down to 10 ms. */
-static int set_utimeout(char *val, char **ret)
+static int set_utimeout(uintmax_t *vp)
 {
-    static char b_ret[4];
-    unsigned long to;
-    char *vend;
+    uintmax_t to = *vp;
 
-    to = strtoul(val, &vend, 10);
-
-    if (to < 10000UL || to > 255000000UL || *vend)
+    if (to < 10000UL || to > 255000000UL)
         return 0;
 
     rexmtval = timeout = to;
     maxtimeout = rexmtval * TIMEOUT_LIMIT;
 
-    sprintf(*ret = b_ret, "%lu", to);
-    return (1);
+    return 1;
 }
 
 /*
- * Parse RFC2347 style options
+ * Conservative calculation for the size of a buffer which can hold an
+ * arbitrary integer
  */
-static void do_opt(char *opt, char *val, char **ap)
+#define OPTBUFSIZE     (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
+
+/*
+ * Parse RFC2347 style options; we limit the arguments to positive
+ * integers which matches all our current options.
+ */
+static void do_opt(const char *opt, const char *val, char **ap)
 {
     struct options *po;
-    char *ret;
+    char retbuf[OPTBUFSIZE];
+    char *p = *ap;
+    size_t optlen, retlen;
+    char *vend;
+    uintmax_t v;
 
     /* Global option-parsing variables initialization */
     blksize_set = 0;
 
-    if (!*opt)
+    if (!*opt || !*val)
+        return;
+
+    errno = 0;
+    v = strtoumax(val, &vend, 10);
+    if (*vend || errno == ERANGE)
         return;
 
     for (po = options; po->o_opt; po++)
         if (!strcasecmp(po->o_opt, opt)) {
-            if (po->o_fnc(val, &ret)) {
-                if (*ap + strlen(opt) + strlen(ret) + 2 >=
-                    ackbuf + sizeof(ackbuf)) {
+            if (po->o_fnc(&v)) {
+               optlen = strlen(opt);
+               retlen = sprintf(retbuf, "%"PRIuMAX, v);
+
+                if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
                     nak(EOPTNEG, "Insufficient space for options");
                     exit(0);
                 }
-                *ap = strrchr(strcpy(strrchr(strcpy(*ap, opt), '\0') + 1,
-                                     ret), '\0') + 1;
+               
+               memcpy(p, opt, optlen+1);
+               p += optlen+1;
+               memcpy(p, retbuf, retlen+1);
+               p += retlen+1;
             } else {
                 nak(EOPTNEG, "Unsupported option(s) requested");
                 exit(0);
             }
             break;
         }
-    return;
+
+    *ap = p;
 }
 
 #ifdef WITH_REGEX

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Remember to have fun...

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to