dhcpcd-7.1.1-v6_read_overflow.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. From c1ebeaafeb324bac997984abdcee2d4e8b61a8a8 Mon Sep 17 00:00:00 2001
  2. From: Roy Marples <roy@marples.name>
  3. Date: Fri, 3 May 2019 14:44:06 +0100
  4. Subject: DHCPv6: Fix a potential read overflow with D6_OPTION_PD_EXCLUDE
  5. dhcpcd only checks that the prefix length of the exclusion
  6. matches the prefix length of the ia and equals the length of the
  7. data in the option.
  8. This could potentially overrun the in6_addr structure.
  9. This is fixed by enforcing RFC 6603 section 4.2 option limits
  10. more clearly.
  11. Thanks to Maxime Villard <max@m00nbsd.net> for finding this.
  12. ---
  13. src/dhcp6.c | 44 +++++++++++++++++++++-----------------------
  14. 1 file changed, 21 insertions(+), 23 deletions(-)
  15. diff --git a/src/dhcp6.c b/src/dhcp6.c
  16. index dee8d4b6..583f3b3f 100644
  17. --- a/src/dhcp6.c
  18. +++ b/src/dhcp6.c
  19. @@ -2166,40 +2166,38 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
  20. state->expire = a->prefix_vltime;
  21. i++;
  22. - o = dhcp6_findoption(o, ol, D6_OPTION_PD_EXCLUDE, &ol);
  23. a->prefix_exclude_len = 0;
  24. memset(&a->prefix_exclude, 0, sizeof(a->prefix_exclude));
  25. -#if 0
  26. - if (ex == NULL) {
  27. - struct dhcp6_option *w;
  28. - uint8_t *wp;
  29. -
  30. - w = calloc(1, 128);
  31. - w->len = htons(2);
  32. - wp = D6_OPTION_DATA(w);
  33. - *wp++ = 64;
  34. - *wp++ = 0x78;
  35. - ex = w;
  36. - }
  37. -#endif
  38. + o = dhcp6_findoption(o, ol, D6_OPTION_PD_EXCLUDE, &ol);
  39. if (o == NULL)
  40. continue;
  41. - if (ol < 2) {
  42. - logerrx("%s: truncated PD Exclude", ifp->name);
  43. +
  44. + /* RFC 6603 4.2 says option length MUST be between 2 and 17.
  45. + * This allows 1 octet for prefix length and 16 for the
  46. + * subnet ID. */
  47. + if (ol < 2 || ol > 17) {
  48. + logerrx("%s: invalid PD Exclude option", ifp->name);
  49. continue;
  50. }
  51. - a->prefix_exclude_len = *o++;
  52. - ol--;
  53. - if (((a->prefix_exclude_len - a->prefix_len - 1) / NBBY) + 1
  54. - != ol)
  55. - {
  56. +
  57. + /* RFC 6603 4.2 says prefix length MUST be between the
  58. + * length of the IAPREFIX prefix length + 1 and 128. */
  59. + if (*o < a->prefix_len + 1 || *o > 128) {
  60. + logerrx("%s: invalid PD Exclude length", ifp->name);
  61. + continue;
  62. + }
  63. +
  64. + /* Check option length matches prefix length. */
  65. + if (((*o - a->prefix_len - 1) / NBBY) + 1 != ol) {
  66. logerrx("%s: PD Exclude length mismatch", ifp->name);
  67. - a->prefix_exclude_len = 0;
  68. continue;
  69. }
  70. - nb = a->prefix_len % NBBY;
  71. +
  72. + a->prefix_exclude_len = *o++;
  73. + ol--;
  74. memcpy(&a->prefix_exclude, &a->prefix,
  75. sizeof(a->prefix_exclude));
  76. + nb = a->prefix_len % NBBY;
  77. if (nb)
  78. ol--;
  79. pw = a->prefix_exclude.s6_addr +
  80. --
  81. cgit v1.2.1
  82. From 896ef4a54b0578985e5e1360b141593f1d62837b Mon Sep 17 00:00:00 2001
  83. From: Roy Marples <roy@marples.name>
  84. Date: Sat, 4 May 2019 10:19:02 +0100
  85. Subject: DHCPv6: Fix exclude prefix length check.
  86. ---
  87. src/dhcp6.c | 4 ++--
  88. 1 file changed, 2 insertions(+), 2 deletions(-)
  89. diff --git a/src/dhcp6.c b/src/dhcp6.c
  90. index 583f3b3f..7f26129f 100644
  91. --- a/src/dhcp6.c
  92. +++ b/src/dhcp6.c
  93. @@ -2187,14 +2187,14 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
  94. continue;
  95. }
  96. + ol--;
  97. /* Check option length matches prefix length. */
  98. if (((*o - a->prefix_len - 1) / NBBY) + 1 != ol) {
  99. logerrx("%s: PD Exclude length mismatch", ifp->name);
  100. continue;
  101. }
  102. -
  103. a->prefix_exclude_len = *o++;
  104. - ol--;
  105. +
  106. memcpy(&a->prefix_exclude, &a->prefix,
  107. sizeof(a->prefix_exclude));
  108. nb = a->prefix_len % NBBY;
  109. --
  110. cgit v1.2.1