Bug 271843 - ppp can crash due to wrapping subtract in FsmRecvEchoReq()
Summary: ppp can crash due to wrapping subtract in FsmRecvEchoReq()
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-06-05 14:46 UTC by Robert Morris
Modified: 2023-06-05 16:43 UTC (History)
1 user (show)

See Also:


Attachments
tickle wrapping subtract in ppp's FsmRecvEchoReq() (4.07 KB, text/plain)
2023-06-05 14:46 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2023-06-05 14:46:04 UTC
Created attachment 242617 [details]
tickle wrapping subtract in ppp's FsmRecvEchoReq()

The follow HDLC frame sent to ppp causes it to dereference a null bp
pointer:

7e
c0 21       -- PROTO_LCP
09 ff 00 03 -- code=9 EchoReply, id=255, length=3
22 96       -- crc
7e

The null bp arises in fsm_Input() in src/usr.sbin/ppp/fsm.c:

  bp = mbuf_Read(bp, &lh, sizeof lh);

mbuf_Read() returns null if it consumes all of the data, which is the
case for the above frame, since sizeof(lh) is four and only the four
bytes 09 ff 00 03 are available.

For the above frame, the null dereference happens in FsmRecvEchoReq().
That function has a length check that could have caught this problem:

  if (lcp && ntohs(lhp->length) - sizeof *lhp >= 4) {

But the ntohs() returns unsigned 3, and the sizeof yields unsigned 4,
so the subtract wraps to unsigned 0xffffffffffffffff, so the code in
the if statement is executed and tries to dereference bp.

Here's a backtrace from the attached demo:

#0  0x000000000003e43c in FsmRecvEchoReq (fp=0x407f71e8, lhp=0x3fffffdd00, 
    bp=0x0) at fsm.c:962
#1  0x000000000003c974 in fsm_Input (fp=0x407f71e8, bp=0x0) at fsm.c:1096
#2  0x000000000004c4be in lcp_Input (bundle=0x97338 <bundle_Create.bundle>, 
    l=0x407f7000, bp=0x407fd300) at lcp.c:1307
#3  0x000000000005002c in Despatch (bundle=0x97338 <bundle_Create.bundle>, 
    l=0x407f7000, bp=0x407fd300, proto=49185) at link.c:381
#4  0x000000000004fefe in link_PullPacket (l=0x407f7000, 
    buf=0x407fa140 "~\377\377~\377\365\275\276\275\177\371\365]\177\346\370\334\354\370\325\346\205\351\326\345\370\370\374\374E|\365\234\314\314\326\346\365\305\346\377\377~\300!\t\377", len=64, b=0x97338 <bundle_Create.bundle>)
    at link.c:323
#5  0x0000000000062b30 in physical_DescriptorRead (d=0x407f7f78, 
    bundle=0x97338 <bundle_Create.bundle>, fdset=0x410069c0) at physical.c:569
#6  0x000000000003221e in datalink_Read (d=0x407f2000, 
    bundle=0x97338 <bundle_Create.bundle>, fdset=0x410069c0) at datalink.c:474
#7  0x000000000001a6e2 in bundle_DescriptorRead (
    d=0x97338 <bundle_Create.bundle>, bundle=0x97338 <bundle_Create.bundle>, 
    fdset=0x410069c0) at bundle.c:546
#8  0x00000000000548a0 in DoLoop (bundle=0x97338 <bundle_Create.bundle>)
    at main.c:661
#9  0x0000000000053d92 in main (argc=3, argv=0x3fffffeb70) at main.c:535