diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2012-08-15 11:26:13 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2012-08-15 11:26:13 +0000 |
commit | 35391fccc49c6bf75e21ca4c3c56fb7ed15fab02 (patch) | |
tree | 2eb72ee1ced970abbe70e4a6de334f8e4a42e0b7 | |
parent | a751b31bde3368f8b18be9b55a3445ffc0d191d3 (diff) | |
download | aports-35391fccc49c6bf75e21ca4c3c56fb7ed15fab02.tar.bz2 aports-35391fccc49c6bf75e21ca4c3c56fb7ed15fab02.tar.xz |
main/busybox: security fix for udhcpcd (CVE-2011-2716)
fixes #1324
-rw-r--r-- | main/busybox/APKBUILD | 4 | ||||
-rw-r--r-- | main/busybox/busybox-1.17-CVE-2011-2716.patch | 193 |
2 files changed, 196 insertions, 1 deletions
diff --git a/main/busybox/APKBUILD b/main/busybox/APKBUILD index 7e62844946..3087ba6845 100644 --- a/main/busybox/APKBUILD +++ b/main/busybox/APKBUILD @@ -1,7 +1,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=busybox pkgver=1.17.4 -pkgrel=1 +pkgrel=2 pkgdesc="Size optimized toolbox of many common UNIX utilities" url=http://busybox.net license="GPL-2" @@ -13,6 +13,7 @@ source="http://busybox.net/downloads/$pkgname-$pkgver.tar.bz2 ifupdown-ipv6.patch $pkgname-1.11.1-bb.patch $pkgname-1.17.4-crond.patch + busybox-1.17-CVE-2011-2716.patch busyboxconfig" _builddir="$srcdir"/$pkgname-$pkgver @@ -73,4 +74,5 @@ md5sums="b3254232e9919007ca803d3a4fe81f3c busybox-1.17.4.tar.bz2 08af7b8b4e41f86a34a16270a8691e31 ifupdown-ipv6.patch 4c0f3b486eaa0674961b7ddcd0c60a9b busybox-1.11.1-bb.patch fd451b1e8e6e976c99869dc2d149ccc9 busybox-1.17.4-crond.patch +c997e21867eac6a87ff55741e2d0ddba busybox-1.17-CVE-2011-2716.patch 403e0b9fe99a7a18c5b9ae91283a5f9a busyboxconfig" diff --git a/main/busybox/busybox-1.17-CVE-2011-2716.patch b/main/busybox/busybox-1.17-CVE-2011-2716.patch new file mode 100644 index 0000000000..ddf291dae2 --- /dev/null +++ b/main/busybox/busybox-1.17-CVE-2011-2716.patch @@ -0,0 +1,193 @@ +From a75807d231c66cf631919736b8694294e93fb18f Mon Sep 17 00:00:00 2001 +From: Denys Vlasenko <vda.linux@googlemail.com> +Date: Thu, 8 Dec 2011 16:41:05 +0100 +Subject: [PATCH] udhcpc: sanitize hostnames in incoming packets. Closes 3979. + +The following options are replaced with string "bad" if they +contain malformed hostname: +HOST_NAME, DOMAIN_NAME, NIS_DOMAIN, TFTP_SERVER_NAME + +function old new delta +xmalloc_optname_optval 850 888 +38 +attach_option 440 443 +3 +len_of_option_as_string 13 14 +1 +dhcp_option_lengths 13 14 +1 +------------------------------------------------------------------------------ +(add/remove: 0/0 grow/shrink: 4/0 up/down: 43/0) Total: 43 bytes + +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> + +Conflicts: + networking/udhcp/dhcpc.c +(cherry picked from commit cd9072e71e5e86c34a6d71c44dde0cafb988d8f1) + +Conflicts: + networking/udhcp/dhcpc.c +(cherry picked from commit 6904feafd1a57bee794a10a928132aaa77855101) + +Conflicts: + networking/udhcp/common.c +--- + networking/udhcp/common.c | 14 +++++++---- + networking/udhcp/common.h | 3 +++ + networking/udhcp/dhcpc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 73 insertions(+), 6 deletions(-) + +diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c +index 90a07ed..6001e84 100644 +--- a/networking/udhcp/common.c ++++ b/networking/udhcp/common.c +@@ -29,15 +29,15 @@ const struct dhcp_optflag dhcp_optflags[] = { + // { OPTION_IP | OPTION_LIST , 0x07 }, /* DHCP_LOG_SERVER */ + // { OPTION_IP | OPTION_LIST , 0x08 }, /* DHCP_COOKIE_SERVER */ + { OPTION_IP | OPTION_LIST , 0x09 }, /* DHCP_LPR_SERVER */ +- { OPTION_STRING | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ ++ { OPTION_STRING_HOST | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ + { OPTION_U16 , 0x0d }, /* DHCP_BOOT_SIZE */ +- { OPTION_STRING | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ ++ { OPTION_STRING_HOST | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ + { OPTION_IP , 0x10 }, /* DHCP_SWAP_SERVER */ + { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ + { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ + { OPTION_U16 , 0x1a }, /* DHCP_MTU */ + { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ +- { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ ++ { OPTION_STRING_HOST , 0x28 }, /* DHCP_NIS_DOMAIN */ + { OPTION_IP | OPTION_LIST , 0x29 }, /* DHCP_NIS_SERVER */ + { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a }, /* DHCP_NTP_SERVER */ + { OPTION_IP | OPTION_LIST , 0x2c }, /* DHCP_WINS_SERVER */ +@@ -45,7 +45,7 @@ const struct dhcp_optflag dhcp_optflags[] = { + { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */ + { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ + //TODO: must be combined with 'sname' and 'file' handling: +- { OPTION_STRING , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ ++ { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ + { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ + //TODO: not a string, but a set of LASCII strings: + // { OPTION_STRING , 0x4D }, /* DHCP_USER_CLASS */ +@@ -130,6 +130,7 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { + [OPTION_IP_PAIR] = 8, + // [OPTION_BOOLEAN] = 1, + [OPTION_STRING] = 1, /* ignored by udhcp_str2optset */ ++ [OPTION_STRING_HOST] = 1, /* ignored by udhcp_str2optset */ + #if ENABLE_FEATURE_UDHCP_RFC3397 + [OPTION_DNS_STRING] = 1, /* ignored by both udhcp_str2optset and xmalloc_optname_optval */ + [OPTION_SIP_SERVERS] = 1, +@@ -398,7 +399,9 @@ static NOINLINE void attach_option( + /* actually 255 is ok too, but adding a space can overlow it */ + + existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length); +- if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING) { ++ if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING ++ || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST ++ ) { + /* add space separator between STRING options in a list */ + existing->data[OPT_DATA + old_len] = ' '; + old_len++; +@@ -462,6 +465,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) + retval = udhcp_str2nip(val, buffer + 4); + break; + case OPTION_STRING: ++ case OPTION_STRING_HOST: + #if ENABLE_FEATURE_UDHCP_RFC3397 + case OPTION_DNS_STRING: + #endif +diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h +index ce81d18..5aed1e6 100644 +--- a/networking/udhcp/common.h ++++ b/networking/udhcp/common.h +@@ -80,6 +80,9 @@ enum { + OPTION_IP = 1, + OPTION_IP_PAIR, + OPTION_STRING, ++ /* Opts of STRING_HOST type will be sanitized before they are passed ++ * to udhcpc script's environment: */ ++ OPTION_STRING_HOST, + // OPTION_BOOLEAN, + OPTION_U8, + OPTION_U16, +diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c +index de1b798..50deea8 100644 +--- a/networking/udhcp/dhcpc.c ++++ b/networking/udhcp/dhcpc.c +@@ -80,6 +80,63 @@ static int mton(uint32_t mask) + return i; + } + ++/* Check if a given label represents a valid DNS label ++ * Return pointer to the first character after the label upon success, ++ * NULL otherwise. ++ * See RFC1035, 2.3.1 ++ */ ++/* We don't need to be particularly anal. For example, allowing _, hyphen ++ * at the end, or leading and trailing dots would be ok, since it ++ * can't be used for attacks. (Leading hyphen can be, if someone uses ++ * cmd "$hostname" ++ * in the script: then hostname may be treated as an option) ++ */ ++static const char *valid_domain_label(const char *label) ++{ ++ unsigned char ch; ++ unsigned pos = 0; ++ ++ for (;;) { ++ ch = *label; ++ if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { ++ if (pos == 0) { ++ /* label must begin with letter */ ++ return NULL; ++ } ++ if (ch < '0' || ch > '9') { ++ if (ch == '\0' || ch == '.') ++ return label; ++ /* DNS allows only '-', but we are more permissive */ ++ if (ch != '-' && ch != '_') ++ return NULL; ++ } ++ } ++ label++; ++ pos++; ++ //Do we want this? ++ //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */ ++ // return NULL; ++ } ++} ++ ++/* Check if a given name represents a valid DNS name */ ++/* See RFC1035, 2.3.1 */ ++static int good_hostname(const char *name) ++{ ++ //const char *start = name; ++ ++ for (;;) { ++ name = valid_domain_label(name); ++ if (!name) ++ return 0; ++ if (!name[0]) ++ return 1; ++ //Do we want this? ++ //return ((name - start) < 1025); /* NS_MAXDNAME */ ++ name++; ++ } ++} ++ + /* Create "opt_name=opt_value" string */ + static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) + { +@@ -130,9 +187,12 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ + break; + } + case OPTION_STRING: ++ case OPTION_STRING_HOST: + memcpy(dest, option, len); + dest[len] = '\0'; +- return ret; /* Short circuit this case */ ++ if (type == OPTION_STRING_HOST && !good_hostname(dest)) ++ safe_strncpy(dest, "bad", len); ++ return ret; + case OPTION_STATIC_ROUTES: { + /* Option binary format: + * mask [one byte, 0..32] +-- +1.7.11.4 + |