diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-11-03 00:10:58 +0200 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-11-03 00:10:58 +0200 |
| commit | 0e4929acd386fd6911825b68d1791c2dd73d3d95 (patch) | |
| tree | 3a9bccecda3ea11087c61172c8a54dfc7d3f5a75 | |
| parent | d80cdc61e82f7beb578f6c8232644f508ec95bb5 (diff) | |
| download | accel-ppp-0e4929acd386fd6911825b68d1791c2dd73d3d95.tar.gz accel-ppp-0e4929acd386fd6911825b68d1791c2dd73d3d95.zip | |
session: read interface stats in the session's own netns
ap_session_read_stats() reached netlink through the thread-local "net".
Callers outside the session's context, such as "show sessions" with
rx-bytes/tx-bytes columns, run on an arbitrary triton thread where
"net" is NULL (never set on that thread) or still points at another
session's namespace: a NULL dereference in iplink_get_stats(), or
counters read from the wrong namespace.
Switch to ses->net around the query and restore it afterwards. Inside
the session's context net == ses->net already, so nothing changes there.
Why not the fixes suggested in the issue: a NULL check in
iplink_get_stats() or net = def_net in the CLI still queries the wrong
namespace for sessions outside the default netns, and reporting cached
counters would make "show sessions" stale.
Fixes #378
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
| -rw-r--r-- | accel-pppd/session.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/accel-pppd/session.c b/accel-pppd/session.c index c16f68ae..c3e03bb6 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -431,6 +431,8 @@ static void generate_sessionid(struct ap_session *ses) int __export ap_session_read_stats(struct ap_session *ses, struct rtnl_link_stats64 *stats) { struct rtnl_link_stats64 lstats; + struct ap_net *saved_net = net; + int r; if (ses->ifindex == -1) return -1; @@ -438,7 +440,16 @@ int __export ap_session_read_stats(struct ap_session *ses, struct rtnl_link_stat if (!stats) stats = &lstats; - if (iplink_get_stats(ses->ifindex, stats)) { + /* ses->ifindex is only valid inside the session's own network + * namespace, so query it through ses->net rather than the thread-local + * net. Within the session's context the two are the same, but callers + * such as the CLI run on an arbitrary triton thread where net may be + * NULL (never set) or still point at another session's namespace. */ + net = ses->net; + r = iplink_get_stats(ses->ifindex, stats); + net = saved_net; + + if (r) { log_ppp_warn("failed to get interface statistics\n"); return -1; } |
