summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-07-07 01:13:29 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-07-07 01:15:06 +0300
commite12b38501be622c9c8e030de86a28721d797e542 (patch)
treefc8abfb28edc5672d6ef3c80ada558d6722a699a
parent7a7ab323158a63f222698f85179090e3b6030b96 (diff)
downloadaccel-ppp-e12b38501be622c9c8e030de86a28721d797e542.tar.gz
accel-ppp-e12b38501be622c9c8e030de86a28721d797e542.zip
ipoe: fix username string leak on early session teardown
The ipoe-level ses->username always holds an allocated string (_strdup of ifname/calling-station-id, u_inet_ntoa buffer or lua result), but ipoe_session_free() never released it. Ownership is normally transferred in auth_result() via ap_session_set_username(), so the string was leaked whenever a session died before auth_result() ran: termination while starting, PWDB_WAIT never completing, or ipoe_create_interface() failure. The create-interface failure path also leaked the freshly allocated local copy outright, since it returned before the string was stored anywhere. Store the string in ses->username as soon as it is obtained and free it in ipoe_session_free(). auth_result() clears ses->username before handing ownership to ap_session_set_username(), so no double free is possible. Reported-by: Louis Scalbert (#101)
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index d7df2f38..18e9228d 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -783,6 +783,10 @@ static void ipoe_session_start(struct ipoe_session *ses)
return;
}
+ /* take ownership now so the string is freed by ipoe_session_free()
+ * even if the session terminates before auth_result() consumes it */
+ ses->username = username;
+
ses->ses.unit_idx = ses->serv->ifindex;
triton_event_fire(EV_CTRL_STARTING, &ses->ses);
@@ -794,7 +798,6 @@ static void ipoe_session_start(struct ipoe_session *ses)
return;
if (conf_noauth) {
- ses->username = username;
r = PWDB_SUCCESS;
} else {
#ifdef RADIUS
@@ -813,7 +816,6 @@ static void ipoe_session_start(struct ipoe_session *ses)
} else
pass = username;
- ses->username = username;
r = pwdb_check(&ses->ses, (pwdb_callback)auth_result, ses, username, PPP_PAP, pass);
if (r == PWDB_WAIT)
@@ -1242,6 +1244,9 @@ static void ipoe_session_free(struct ipoe_session *ses)
if (ses->l4_redirect_ipset)
_free(ses->l4_redirect_ipset);
+ if (ses->username)
+ _free(ses->username);
+
triton_context_unregister(&ses->ctx);
if (ses->data)