[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(usagi-users 03061) Bug in function inet6_rth_add of libinet6.a
- To: usagi-users@xxxxxxxxxxxxxx
- Subject: (usagi-users 03061) Bug in function inet6_rth_add of libinet6.a
- From: Jean-Luc Richier <Jean-Luc.Richier@xxxxxxx>
- Date: Thu, 07 Oct 2004 19:03:01 +0200
- Reply-to: usagi-users@xxxxxxxxxxxxxx
- User-agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.0.2) Gecko/20030708
kernel: 2.4.20-30.7.legacy (Redhat 7.3, non USAGI)
Usagi versions tested: usagi-tool-stable-20030214.tar.bz2 and
usagi-linux24-s20040927.tar.bz2
glibc: glibc-2.2.5-44
Description
===========
The function inet6_rth_add inlibinet6.a which adds an entry in a IPv6
routing header option does not work. It adds the entry at a wrong offset.
Note: By comparison with the libinet rthdr code in KAME FreeBSD code,
the functions inet6_rthdr_getaddr inet6_rth_reverse inet6_rth_getaddr
are also probably incorrect.
How to test
===========
Write a program which send a packet which sendmsg and a routing option
created
with inet6_rth_* with 2 routing segments
(the program works with FreeBSD4/Kame, Solaris 10, FreeBSD5),
and dump the control buffer of the sendmsg:
(gdb) n
105 ret = sendmsg(sock, &msg, flags);
(gdb) p msg
$2 = {msg_name = 0x804dd78, msg_namelen = 28, msg_iov = 0xbfffe220,
msg_iovlen = 1, msg_control = 0x804dda8, msg_controllen = 52,
msg_flags = 0}
(gdb) x/3wx 0x804dda8
0x804dda8: 0x00000034 0x00000029 0x00000005
(gdb) x/40bx
0x804ddb4: 0x00 0x04 0x00 0x02 0x00 0x00 0x00 0x00
0x804ddbc: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804ddc4: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804ddcc: 0x20 0x01 0x02 0x00 0x00 0x00 0x80 0x02
0x804ddd4: 0x02 0x03 0x47 0xff 0xfe 0xa5 0x30 0x85
(gdb) c
Continuing.
send_data: sendmsg: Network is unreachable
send_echo_request6: : Illegal seek
One see that the first routing segment address (at 0x804ddbc) is null
and the second one (at 0x804ddcc) contains an IPv6 address whih is the
first relay address.
Cause
=====
The bug comes from an incorrect use or declaration of struct ip6_rthdr0
in libinet6/rthdr.c and libinet6/include_glibc/netinet/ip6.h:
In libinet6/include_glibc/netinet/ip6.h the struct ip6_rthdr0 is
/* Type 0 Routing header */
struct ip6_rthdr0
{
uint8_t ip6r0_nxt; /* next header */
uint8_t ip6r0_len; /* length in units of 8 octets */
uint8_t ip6r0_type; /* always zero */
uint8_t ip6r0_segleft; /* segments left */
uint8_t ip6r0_reserved; /* reserved field */
uint8_t ip6r0_slmap[3]; /* strict/loose bit map */
struct in6_addr ip6r0_addr[1]; /* XXX: removed in RFC2292bis */
};
but in libinet6/rthdr.c the first address is supposed to be at
nextaddr = (struct in6_addr *)(rth0 + 1)
that is AFTER the ip6r0_addr field.
How to correct
=============
There is 2 possible corrections
- Either correct "struct ip6_rthdr0" in
libinet6/include_glibc/netinet/ip6.h by suppressing the removed field
ip6r0_addr[1], in concordance with the latest RFC 3542
(and adding comment: /* followed by up to 127 struct in6_addr */)
That is the FreeBSD/KAME solution
this can impact on other functions, at least net6_rthdr_space and
inet6_rthdr_init
Suppressing the -DCOMPAT_RFC2292 flag in the Makefile.in should correct
this.
Also the file libinet6/include_glibc/netinet/ip6.h diverges with the
kernel linux /usr/include/netinet/ip6.h (but respects the latest RFC)
- Or correct libinet6/rthdr.c with the following patch:
diff -u rthdr.c*
--- rthdr.c Wed May 15 07:45:20 2002
+++ rthdr.c.NEW Thu Oct 7 18:13:01 2004
@@ -414,7 +414,7 @@
switch(rth->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rth0 = (struct ip6_rthdr0 *)rth;
- nextaddr = (struct in6_addr *)(rth0 + 1) +
rth0->ip6r0_segleft;
+ nextaddr = &rth0->ip6r0_addr[rth0->ip6r0_segleft];
*nextaddr = *addr;
rth0->ip6r0_segleft++;
break;
However the functions inet6_rthdr_getaddr inet6_rth_reverse and
inet6_rth_getaddr should probably be corrected in the same manner.
--
Jean-Luc RICHIER (Jean-Luc.Richier@xxxxxxx richier@xxxxxxx)
Laboratoire Logiciels, Systemes et Reseaux (LSR-IMAG)
IMAG-CAMPUS, BP 72, F-38402 St Martin d'Heres Cedex
Tel : +33 4 76 82 72 32 Fax : +33 4 76 82 72 87