[Bug 271820] libalias's AliasHandleQuestion() can run off the end of a ppp packet
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 271820] libalias's AliasHandleQuestion() can run off the end of a ppp packet"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 271820] libalias's AliasHandleQuestion() can run off the end of a ppp packet"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 04 Jun 2023 15:08:13 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271820
Bug ID: 271820
Summary: libalias's AliasHandleQuestion() can run off the end
of a ppp packet
Product: Base System
Version: CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: bin
Assignee: bugs@FreeBSD.org
Reporter: rtm@lcs.mit.edu
Attachment #242592 text/plain
mime type:
Created attachment 242592
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=242592&action=edit
send ppp -nat a packet that causes AliasHandleQuestion() to run off the end of
a buffer
I've attached a program which sends a short packet into ppp -nat, UDP, sport
137 (NetBios NS). The IP and UDP headers that libalias sees:
(gdb) print/x *pip
$26 = {ip_hl = 0x0, ip_v = 0x0, ip_tos = 0x89, ip_len = 0x4600, ip_id = 0xffff,
ip_off = 0xe0, ip_ttl = 0xff, ip_p = 0x11, ip_sum = 0xff7f, ip_src = {
s_addr = 0xffffff7f}, ip_dst = {s_addr = 0x7fff7fff}}
(gdb) print/x *uh
$27 = {uh_sport = 0x8900, uh_dport = 0x4600, uh_ulen = 0xffff, uh_sum = 0xe0}
What ultimately happens is that libalias/alias_nbt.c's
AliasHandleQuestion() thinks the UDP packet is 65536 bytes long, due
to uh_ulen, but the actual packet buffer is only 70 bytes long, so
AliasHandleQuestion() reads off the end of the packet. That can cause
ppp to crash, though it doesn't always.
ValidateUdpLength() doesn't reject the crazy uh_ulen because the IP_MF
flag is set in ip_off.
LibAliasInLocked() doesn't reject the crazy ip_hl of zero; it only
checks for ip_hl too large.
To see this with the attached program:
# cc -g ppp2b.c
# gdb a.out
(gdb) set follow-fork-mode child
(gdb) catch exec
(gdb) run
...
(gdb) break AliasHandleQuestion
(gdb) c
...
(gdb) print (char*)pmax - (char*)q
$1 = 65515
(gdb) up
(gdb) print/x pip->ip_len
$2 = 0x4600
*** 65515 is much bigger than the packet ***
(gdb) where
#0 AliasHandleQuestion (count=32767, q=0x801c7114c, pmax=0x801c81137 "",
nbtarg=<optimized out>) at /usr/src/sys/netinet/libalias/alias_nbt.c:426
#1 AliasHandleUdpNbtNS (la=<optimized out>, pip=0x801c71138, lnk=<optimized
out>, alias_address=<optimized out>, alias_port=<optimized out>,
original_address=<optimized out>,
original_port=0x801c7113a) at /usr/src/sys/netinet/libalias/alias_nbt.c:807
#2 0x00000008010d0ccf in protohandler2in (la=<optimized out>, pip=0x801c71138,
ah=<optimized out>) at /usr/src/sys/netinet/libalias/alias_nbt.c:114
#3 0x00000008011306b5 in UdpAliasIn (la=la@entry=0x801c1a000,
pip=pip@entry=0x801c71138) at /usr/src/sys/netinet/libalias/alias.c:786
#4 0x000000080112f93c in LibAliasInLocked (la=0x801c1a000,
pip=pip@entry=0x801c71138, maxpacketsize=<optimized out>) at
/usr/src/sys/netinet/libalias/alias.c:1364
#5 0x000000080112f787 in LibAliasIn (la=0x801c71138, ptr=0x7fff,
ptr@entry=0x801c71138, maxpacketsize=0) at
/usr/src/sys/netinet/libalias/alias.c:1325
#6 0x0000000001088452 in nat_LayerPull (bundle=0x10974b0
<bundle_Create.bundle>, l=<optimized out>, bp=0x801c71100, proto=<optimized
out>) at /usr/src/usr.sbin/ppp/nat_cmd.c:532
#7 0x0000000001070ff4 in link_PullPacket (l=0x801c4d600, buf=<optimized out>,
len=<optimized out>, b=0x10974b0 <bundle_Create.bundle>) at
/usr/src/usr.sbin/ppp/link.c:315
#8 0x000000000104ae25 in bundle_DescriptorRead (d=<optimized out>,
bundle=0x10974b0 <bundle_Create.bundle>, fdset=0x801c78140) at
/usr/src/usr.sbin/ppp/bundle.c:546
#9 0x0000000001074704 in DoLoop (bundle=0x10974b0 <bundle_Create.bundle>) at
/usr/src/usr.sbin/ppp/main.c:661
#10 main (argc=3, argv=<optimized out>) at /usr/src/usr.sbin/ppp/main.c:535
--
You are receiving this mail because:
You are the assignee for the bug.