006-upstream_CVE-2011-2716_fixes.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. --- a/networking/udhcp/common.c
  2. +++ b/networking/udhcp/common.c
  3. @@ -29,16 +29,16 @@ const struct dhcp_optflag dhcp_optflags[
  4. // { OPTION_IP | OPTION_LIST , 0x07 }, /* DHCP_LOG_SERVER */
  5. // { OPTION_IP | OPTION_LIST , 0x08 }, /* DHCP_COOKIE_SERVER */
  6. { OPTION_IP | OPTION_LIST , 0x09 }, /* DHCP_LPR_SERVER */
  7. - { OPTION_STRING | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */
  8. + { OPTION_STRING_HOST | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */
  9. { OPTION_U16 , 0x0d }, /* DHCP_BOOT_SIZE */
  10. - { OPTION_STRING | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */
  11. + { OPTION_STRING_HOST | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */
  12. { OPTION_IP , 0x10 }, /* DHCP_SWAP_SERVER */
  13. { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */
  14. { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */
  15. { OPTION_U16 , 0x1a }, /* DHCP_MTU */
  16. { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */
  17. { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */
  18. - { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */
  19. + { OPTION_STRING_HOST , 0x28 }, /* DHCP_NIS_DOMAIN */
  20. { OPTION_IP | OPTION_LIST , 0x29 }, /* DHCP_NIS_SERVER */
  21. { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a }, /* DHCP_NTP_SERVER */
  22. { OPTION_IP | OPTION_LIST , 0x2c }, /* DHCP_WINS_SERVER */
  23. @@ -46,7 +46,7 @@ const struct dhcp_optflag dhcp_optflags[
  24. { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */
  25. { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */
  26. //TODO: must be combined with 'sname' and 'file' handling:
  27. - { OPTION_STRING , 0x42 }, /* DHCP_TFTP_SERVER_NAME */
  28. + { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */
  29. { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */
  30. //TODO: not a string, but a set of LASCII strings:
  31. // { OPTION_STRING , 0x4D }, /* DHCP_USER_CLASS */
  32. @@ -143,6 +143,7 @@ const uint8_t dhcp_option_lengths[] ALIG
  33. [OPTION_IP_PAIR] = 8,
  34. // [OPTION_BOOLEAN] = 1,
  35. [OPTION_STRING] = 1, /* ignored by udhcp_str2optset */
  36. + [OPTION_STRING_HOST] = 1, /* ignored by udhcp_str2optset */
  37. #if ENABLE_FEATURE_UDHCP_RFC3397
  38. [OPTION_DNS_STRING] = 1, /* ignored by both udhcp_str2optset and xmalloc_optname_optval */
  39. [OPTION_SIP_SERVERS] = 1,
  40. @@ -411,7 +412,9 @@ static NOINLINE void attach_option(
  41. /* actually 255 is ok too, but adding a space can overlow it */
  42. existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length);
  43. - if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING) {
  44. + if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING
  45. + || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST
  46. + ) {
  47. /* add space separator between STRING options in a list */
  48. existing->data[OPT_DATA + old_len] = ' ';
  49. old_len++;
  50. @@ -475,6 +478,7 @@ int FAST_FUNC udhcp_str2optset(const cha
  51. retval = udhcp_str2nip(val, buffer + 4);
  52. break;
  53. case OPTION_STRING:
  54. + case OPTION_STRING_HOST:
  55. #if ENABLE_FEATURE_UDHCP_RFC3397
  56. case OPTION_DNS_STRING:
  57. #endif
  58. --- a/networking/udhcp/common.h
  59. +++ b/networking/udhcp/common.h
  60. @@ -80,6 +80,9 @@ enum {
  61. OPTION_IP = 1,
  62. OPTION_IP_PAIR,
  63. OPTION_STRING,
  64. + /* Opts of STRING_HOST type will be sanitized before they are passed
  65. + * to udhcpc script's environment: */
  66. + OPTION_STRING_HOST,
  67. // OPTION_BOOLEAN,
  68. OPTION_U8,
  69. OPTION_U16,
  70. --- a/networking/udhcp/dhcpc.c
  71. +++ b/networking/udhcp/dhcpc.c
  72. @@ -101,6 +101,7 @@ static const uint8_t len_of_option_as_st
  73. [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2,
  74. [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "),
  75. [OPTION_STRING ] = 1,
  76. + [OPTION_STRING_HOST ] = 1,
  77. #if ENABLE_FEATURE_UDHCP_RFC3397
  78. [OPTION_DNS_STRING ] = 1, /* unused */
  79. /* Hmmm, this severely overestimates size if SIP_SERVERS option
  80. @@ -135,6 +136,63 @@ static int mton(uint32_t mask)
  81. return i;
  82. }
  83. +/* Check if a given label represents a valid DNS label
  84. + * Return pointer to the first character after the label upon success,
  85. + * NULL otherwise.
  86. + * See RFC1035, 2.3.1
  87. + */
  88. +/* We don't need to be particularly anal. For example, allowing _, hyphen
  89. + * at the end, or leading and trailing dots would be ok, since it
  90. + * can't be used for attacks. (Leading hyphen can be, if someone uses
  91. + * cmd "$hostname"
  92. + * in the script: then hostname may be treated as an option)
  93. + */
  94. +static const char *valid_domain_label(const char *label)
  95. +{
  96. + unsigned char ch;
  97. + unsigned pos = 0;
  98. +
  99. + for (;;) {
  100. + ch = *label;
  101. + if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
  102. + if (pos == 0) {
  103. + /* label must begin with letter */
  104. + return NULL;
  105. + }
  106. + if (ch < '0' || ch > '9') {
  107. + if (ch == '\0' || ch == '.')
  108. + return label;
  109. + /* DNS allows only '-', but we are more permissive */
  110. + if (ch != '-' && ch != '_')
  111. + return NULL;
  112. + }
  113. + }
  114. + label++;
  115. + pos++;
  116. + //Do we want this?
  117. + //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */
  118. + // return NULL;
  119. + }
  120. +}
  121. +
  122. +/* Check if a given name represents a valid DNS name */
  123. +/* See RFC1035, 2.3.1 */
  124. +static int good_hostname(const char *name)
  125. +{
  126. + //const char *start = name;
  127. +
  128. + for (;;) {
  129. + name = valid_domain_label(name);
  130. + if (!name)
  131. + return 0;
  132. + if (!name[0])
  133. + return 1;
  134. + //Do we want this?
  135. + //return ((name - start) < 1025); /* NS_MAXDNAME */
  136. + name++;
  137. + }
  138. +}
  139. +
  140. /* Create "opt_name=opt_value" string */
  141. static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name)
  142. {
  143. @@ -185,8 +243,11 @@ static NOINLINE char *xmalloc_optname_op
  144. break;
  145. }
  146. case OPTION_STRING:
  147. + case OPTION_STRING_HOST:
  148. memcpy(dest, option, len);
  149. dest[len] = '\0';
  150. + if (type == OPTION_STRING_HOST && !good_hostname(dest))
  151. + safe_strncpy(dest, "bad", len);
  152. return ret; /* Short circuit this case */
  153. case OPTION_STATIC_ROUTES: {
  154. /* Option binary format:
  155. @@ -314,6 +375,7 @@ static char **fill_envp(struct dhcp_pack
  156. /* +1 element for each option, +2 for subnet option: */
  157. if (packet) {
  158. /* note: do not search for "pad" (0) and "end" (255) options */
  159. +//TODO: change logic to scan packet _once_
  160. for (i = 1; i < 255; i++) {
  161. temp = udhcp_get_option(packet, i);
  162. if (temp) {