xebd / accel-ppp

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

stack-buffer-underflow in reload_exec #154

Open GoldBinocle opened 2 years ago

GoldBinocle commented 2 years ago

Using version accel-ppp version 1.12.0-149-gff91c73

The function reload_exec can cause stack-buffer-underflow:

Here is the asan report:

=================================================================
==412981==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffff28f7e80 at pc 0x000000499da7 bp 0x7ffff28f7d40 sp 0x7ffff28f7508
READ of size 4000 at 0x7ffff28f7e80 thread T7
[Detaching after fork from child process 414134]
    #0 0x499da6 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 0x7ffff7fb7ee6 in alloc_context /root/projects/accel-ppp/accel-pppd/triton/triton.c:485:2
    #2 0x7ffff7fb5357 in triton_context_schedule /root/projects/accel-ppp/accel-pppd/triton/triton.c:497:12
    #3 0x5152ad in reload_exec /root/projects/accel-ppp/accel-pppd/cli/std_cmd.c:341:3
    #4 0x528aec in cli_process_simple_cmd /root/projects/accel-ppp/accel-pppd/cli/cli.c:267:10
    #5 0x5277ca in cli_process_cmd /root/projects/accel-ppp/accel-pppd/cli/cli.c:290:11
    #6 0x524de4 in cln_read /root/projects/accel-ppp/accel-pppd/cli/tcp.c:180:5
    #7 0x7ffff7fb7633 in ctx_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:252:10
    #8 0x7ffff7fb3eb8 in triton_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:192:5
    #9 0x7ffff7f72608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477:8
    #10 0x7ffff794b292 in clone /build/glibc-eX1tMB/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Address 0x7ffff28f7e80 is located in stack of thread T7 at offset 0 in frame
    #0 0x52860f in cli_process_simple_cmd /root/projects/accel-ppp/accel-pppd/cli/cli.c:248

  This frame has 1 object(s):
    [32, 832) 'items' (line 251) <== Memory access at offset 0 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 0x484d5c 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 0x7ffff7fb2fa7 in create_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:320:9
    #2 0x7ffff7fb6987 in triton_run /root/projects/accel-ppp/accel-pppd/triton/triton.c:744:7
    #3 0x54704d in main /root/projects/accel-ppp/accel-pppd/main.c:407:2
    #4 0x7ffff78500b2 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:
  0x10007e516f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007e516fd0:[f1]f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e516ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e517000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e517010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007e517020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==412981==ABORTING

Steps to reproduce

  1. Build:
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
  1. Run access-pppd
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=pptp
 #ipv6-pool=pptp
 #ipv6-pool-delegate=pptp
 #ifname=pptp%d

 [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=eth0

 [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]
 10.0.0.0/8

 [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
 #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
  1. Connect 127.0.0.1:2001 using nc:
nc 127.0.0.1 2001

then type reload to reload the configure file. Then the accel-pppd will crash due to stack-buffer-underflow.

DmitriyEshenko commented 2 years ago

Hello @GoldBinocle , can you try to reproduce it with defined PID? accel-pppd -c /etc/accel-ppp.conf -p /run/accel-ppp.pid

GoldBinocle commented 2 years ago

Hi, @DmitriyEshenko. Yeah, I can reproduce it using -p, and it's the same error.