aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-03-10 11:47:58 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-03-10 11:47:58 +0100
commitd474ffc68290e0a83651c4432eeabfa62cd51e87 (patch)
treee2ac94fcab17bdf31bd70de2e92bce79eabfa21f
parentd2b820b540ada43dfef8751328c158e342387304 (diff)
downloadbusybox-w32-d474ffc68290e0a83651c4432eeabfa62cd51e87.tar.gz
busybox-w32-d474ffc68290e0a83651c4432eeabfa62cd51e87.tar.bz2
busybox-w32-d474ffc68290e0a83651c4432eeabfa62cd51e87.zip
udhcp: fix a SEGV on malformed RFC1035-encoded domain name
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/domain_codec.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c
index 05cdf51e9..cee31f14d 100644
--- a/networking/udhcp/domain_codec.c
+++ b/networking/udhcp/domain_codec.c
@@ -63,11 +63,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
63 if (crtpos + *c + 1 > clen) /* label too long? abort */ 63 if (crtpos + *c + 1 > clen) /* label too long? abort */
64 return NULL; 64 return NULL;
65 if (dst) 65 if (dst)
66 memcpy(dst + len, c + 1, *c); 66 /* \3com ---> "com." */
67 ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.';
67 len += *c + 1; 68 len += *c + 1;
68 crtpos += *c + 1; 69 crtpos += *c + 1;
69 if (dst)
70 dst[len - 1] = '.';
71 } else { 70 } else {
72 /* NUL: end of current domain name */ 71 /* NUL: end of current domain name */
73 if (retpos == 0) { 72 if (retpos == 0) {
@@ -78,7 +77,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
78 crtpos = retpos; 77 crtpos = retpos;
79 retpos = depth = 0; 78 retpos = depth = 0;
80 } 79 }
81 if (dst) 80 if (dst && len != 0)
81 /* \4host\3com\0\4host and we are at \0:
82 * \3com was converted to "com.", change dot to space.
83 */
82 dst[len - 1] = ' '; 84 dst[len - 1] = ' ';
83 } 85 }
84 86
@@ -227,6 +229,9 @@ int main(int argc, char **argv)
227 int len; 229 int len;
228 uint8_t *encoded; 230 uint8_t *encoded;
229 231
232 uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 };
233 printf("NUL:'%s'\n", dname_dec(str, 6, ""));
234
230#define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) 235#define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre))
231 printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); 236 printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:"));
232 printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", "")); 237 printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", ""));