diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-03-10 11:47:58 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-03-10 11:47:58 +0100 |
| commit | d474ffc68290e0a83651c4432eeabfa62cd51e87 (patch) | |
| tree | e2ac94fcab17bdf31bd70de2e92bce79eabfa21f | |
| parent | d2b820b540ada43dfef8751328c158e342387304 (diff) | |
| download | busybox-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.c | 13 |
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", "")); |
