kern/99425: ping6 memory leak due to IPV6_RTHDR setsockopt behavior
and inet6_rth_* functions.
Clément Lecigne
clemun at gmail.com
Sat Jun 24 16:00:47 UTC 2006
>Number: 99425
>Category: kern
>Synopsis: ping6 memory leak due to IPV6_RTHDR setsockopt behavior and inet6_rth_* functions.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Jun 24 16:00:34 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Clément Lecigne
>Release: 6.1
>Organization:
>Environment:
FreeBSD pouik 6.1-STABLE FreeBSD 6.1-STABLE #0: Mon May 29 06:09:07 CEST 2006 clem1 at pouik:/usr/src/sys/i386/compile/GENERIC i386
>Description:
$ ping6 -v -h 255 `perl -e 'print "::1 "x124'`
PING6(56=40+8+8 bytes) ::1 --> ::1
16 bytes from ::1: Echo Request
Routing: nxt 58, len 246 (1976 bytes), type 0, 123 segments, 0 left
[1]::1
(...)
[57]::1
[58]::1
[59]::208.231.191.191
[60]1c00:0:80e2:bfbf:100:0:90e2:bfbf
[61]4:0:2000:0:9060:728::
[62]f4e6:bfbf:d45d:528:4050:708:90e2:bfbf
[63]1c00:0:7b00:0:100:0:ffff:ffff
[64]ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
[65]ffff:ffff:ffff:ffff:ffff:ffff::
[66]84e7:bfbf:a35e:528:100:0:58e7:bfbf
[67]100:0:5ce7:bfbf:0:528:50:728
(...)
When we specify a larger number of intermediate hops with verbose output, ping6 displays stack data whereas ::1 after the 58th hop.
This bug can be reveal data stored on stack and seems due to a behavior of setsockopt with IPV6_RTHDR optname and the absence of bound checkings in inet6_rth_* functions from /usr/src/lib/libc/net/rthdr.c.
setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR, (void *)rthdr, (rthdr->ip6r_len + 1) << 3);
If rthdr size is greater than approximatively 936 bytes (~60 segments), only rthdr first 936 bytes will be considered and sended in the routing extension header without altering rthdr->ip6r_len or rthdr->ip6r_segment.
ping6 calls init6_rth_segments() function which returns the rthdr->ip6r_segment value without checking if it's true...
>How-To-Repeat:
ping6 -v -h 255 `perl -e 'print "::1 "x124'`
>Fix:
What RFC3542 said about that ?
"For an IPv6 Type 0 Routing header, the number of segments must be between 0 and 127, inclusive."
The old init6_rthdr_space make sure that segment value is between 1 and 23.
To be compliant with the RFC, it seems that we must:
- check that segment value is between 0 and 127 (inclusive) in init6_rth_space, if not return 0.
- check that ip6r_segment is not greater than 127 in init6_rth_add.
- increase buffer size (optbuf_storage) in ip6_output.c (line 1767) to hold the possible 128 segments.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list