Hello community,
here is the log from the commit of package tftp for openSUSE:11.4
checked in at Fri Jun 24 16:16:50 CEST 2011.
--------
--- old-versions/11.4/all/tftp/tftp.changes 2010-12-11 01:00:45.000000000 +0100
+++ 11.4/tftp/tftp.changes 2011-06-24 09:16:04.000000000 +0200
@@ -1,0 +2,8 @@
+Wed Jun 22 13:15:44 UTC 2011 - puzel@novell.com
+
+- fix buffer overflow (bnc#699714)
+ - tftp-hpa-CVE-2011-2199.patch
+- unbreak tftp by changing to user to run as in tftpd itself,
+ not via xinetd (bnc#682340)
+
+-------------------------------------------------------------------
Package does not exist at destination yet. Using Fallback old-versions/11.4/all/tftp
Destination is old-versions/11.4/UPDATES/all/tftp
calling whatdependson for 11.4-i586
New:
----
tftp-hpa-CVE-2011-2199.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ tftp.spec ++++++
--- /var/tmp/diff_new_pack.pjaHqg/_old 2011-06-24 16:13:55.000000000 +0200
+++ /var/tmp/diff_new_pack.pjaHqg/_new 2011-06-24 16:13:55.000000000 +0200
@@ -1,7 +1,7 @@
#
-# spec file for package tftp (Version 5.0)
+# 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
@@ -19,7 +19,7 @@
Name: tftp
Version: 5.0
-Release: 1
+Release: 113.<RELEASE114>
License: BSD3c
Summary: Trivial File Transfer Protocol (TFTP)
Url: http://www.kernel.org/pub/software/network/tftp/
@@ -30,6 +30,7 @@
Patch1: tftp-hpa-0.46_colon_check.patch
Patch4: tftp-hpa-0.49-fortify-strcpy-crash.patch
Patch5: tftp-hpa-0.48-tzfix.patch
+Patch6: tftp-hpa-CVE-2011-2199.patch
Patch42: tftp-hpa-0.43_old-autoconf.diff
BuildRequires: pwdutils
BuildRequires: tcpd-devel
@@ -52,6 +53,7 @@
%patch1
%patch4 -p1
%patch5 -p1
+%patch6 -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
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
Signed-off-by: H. Peter Anvin
Signed-off-by: Petr Uzel
---
tftpd/tftpd.c | 154 +++++++++++++++++++++++++++------------------------------
1 files changed, 73 insertions(+), 81 deletions(-)
Index: tftp-hpa-5.0/tftpd/tftpd.c
===================================================================
--- tftp-hpa-5.0.orig/tftpd/tftpd.c
+++ tftp-hpa-5.0/tftpd/tftpd.c
@@ -113,18 +113,18 @@ 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_rollover(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 *);
+static int set_rollover(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},
@@ -1111,48 +1111,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;
-
- 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);
else if (sz > max_blksize)
sz = max_blksize;
+ else
/* Convert to a power of two */
if (sz & (sz - 1)) {
@@ -1163,28 +1153,22 @@ 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;
}
/*
* Set the block number rollover value
*/
-static int set_rollover(char *val, char **ret)
+static int set_rollover(uintmax_t *vp)
{
- uintmax_t ro;
- char *vend;
+ uintmax_t ro = *vp;
- ro = strtoumax(val, &vend, 10);
- if (ro > 65535 || *vend)
+ if (ro > 65535)
return 0;
rollover_val = (uint16_t)ro;
- *ret = val;
return 1;
}
@@ -1193,22 +1177,18 @@ static int set_rollover(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;
+ uintmax_t sz = *vp;
- sz = strtoumax(val, &vend, 10);
-
- 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;
}
/*
@@ -1216,74 +1196,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;
-
- to = strtoul(val, &vend, 10);
+ uintmax_t to = *vp;
- 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
+ */
+#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(char *opt, char *val, char **ap)
+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
++++++ tftp.xinetd ++++++
--- /var/tmp/diff_new_pack.pjaHqg/_old 2011-06-24 16:13:55.000000000 +0200
+++ /var/tmp/diff_new_pack.pjaHqg/_new 2011-06-24 16:13:55.000000000 +0200
@@ -11,9 +11,9 @@
protocol = udp
wait = yes
flags = IPv6 IPv4
- user = tftp
+ user = root
server = /usr/sbin/in.tftpd
- server_args = -s /srv/tftpboot
+ server_args = -u tftp -s /srv/tftpboot
# per_source = 11
# cps = 100 2
disable = yes
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org