Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memery leak bugs when exits or reload #155

Open
GoldBinocle opened this issue Oct 4, 2021 · 0 comments
Open

Memery leak bugs when exits or reload #155

GoldBinocle opened this issue Oct 4, 2021 · 0 comments

Comments

@GoldBinocle
Copy link

There are some memery leak bugs.

The memory allocated to pool in ippool_init2 is not free when exits.

static void ippool_init2(void)
{
struct conf_sect_t *s = conf_get_section("ip-pool");
struct conf_option_t *opt;
struct ippool_t *pool, *next;
generate_func generate;
if (!s)
return;
def_pool = create_pool(NULL);
list_for_each_entry(opt, &s->items, entry) {
#ifdef RADIUS
if (triton_module_loaded("radius")) {
if (!strcmp(opt->name, "vendor")) {
conf_vendor = parse_vendor_opt(opt->val);
continue;
} else if (!strcmp(opt->name, "attr")) {
conf_attr = parse_attr_opt(opt->val);
continue;
}
}
#endif
if (!strcmp(opt->name, "gw-ip-address"))
parse_gw_ip_address(opt->val);
else if (!strcmp(opt->name, "shuffle"))
conf_shuffle = atoi(opt->val);
else {
if (parse_options(opt->raw, &pool, &generate, &next)) {
log_error("ippool: failed to parse '%s'\n", opt->raw);
continue;
}
if (!strcmp(opt->name, "gw"))
add_range(pool, &pool->gw_list, opt->val, generate);
else if (!strcmp(opt->name, "tunnel"))
add_range(pool, &pool->tunnel_list, opt->val, generate);
else if (!opt->val || strchr(opt->name, ','))
add_range(pool, &pool->tunnel_list, opt->name, generate);
if (next)
pool->next = next;
}
}
if (def_pool->generate)
def_pool->generate(def_pool);
list_for_each_entry(pool, &pool_list, entry) {
if (pool->generate)
pool->generate(pool);
else
log_warn("ippool: pool '%s' is empty or not defined\n", pool->name);
}
#ifdef USE_BACKUP
backup_register_module(&backup_mod);
#endif
#ifdef RADIUS
if (triton_module_loaded("radius"))
triton_event_register_handler(EV_RADIUS_ACCESS_ACCEPT, (triton_event_func)ev_radius_access_accept);
#endif
}

Similarly, the memory allocated to threads is not free when exits or reloads the configure file

static LIST_HEAD(threads);

reload code:
static void __config_reload(void (*notify)(int))
{
struct _triton_thread_t *t;
int r;
log_debug2("config_reload: enter\n");
r = conf_reload(NULL);
notify(r);
spin_lock(&threads_lock);
need_config_reload = 0;
list_for_each_entry(t, &threads, entry)
triton_thread_wakeup(t);
spin_unlock(&threads_lock);
log_debug2("config_reload: exit\n");
}

Steps to reproduce(for example)

  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 (which is not important for reproducing):

[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 shutdown. Then the accel-pppd will crash due to memory leaks. Here is the ASAN report:

=================================================================
==555172==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 36720 byte(s) in 1530 object(s) allocated from:
    #0 0x49a9fd in malloc /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
    #1 0x7f84d9f0579e in add_range /root/projects/accel-ppp/accel-pppd/extra/ippool.c:176:8
    #2 0x7f84d9f04107 in ippool_init2 /root/projects/accel-ppp/accel-pppd/extra/ippool.c:642:5
    #3 0x7f84dd58e63d in triton_load_modules /root/projects/accel-ppp/accel-pppd/triton/triton.c:704:3
    #4 0x547018 in main /root/projects/accel-ppp/accel-pppd/main.c:402:6
    #5 0x7f84dce280b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

Direct leak of 640 byte(s) in 4 object(s) allocated from:
    #0 0x49a9fd in malloc /home/brian/src/llvm_releases/llvm-project/llvm/utils/release/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
    #1 0x7f84dd58ae3a in create_thread /root/projects/accel-ppp/accel-pppd/triton/triton.c:302:36
    #2 0x7f84dd58e987 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 0x7f84dce280b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: 37360 byte(s) leaked in 1534 allocation(s).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant