diff options
author | Evgenii Bendyak <jman.box@gmail.com> | 2024-04-30 16:51:53 +0300 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2024-04-30 18:15:26 +0200 |
commit | 27d8c2075054c4e83f3630e2c56d261b66ed9a93 (patch) | |
tree | 11ec41322d5873d6d65405ac8e2973c235f519e0 /src | |
parent | 67b546e01469060c398a49a8ce1ff2c9073db526 (diff) |
fix bug in race condition of calling nflog_open from different threads at same time
This patch addresses a bug that occurs when the nflog_open function is
called concurrently from different threads within an application. The
function nflog_open internally invokes nflog_open_nfnl. Within this
function, a static global variable pkt_cb (static struct nfnl_callback
pkt_cb) is used. This variable is assigned a pointer to a newly created
structure (pkt_cb.data = h;) and is passed to nfnl_callback_register.
The issue arises with concurrent execution of pkt_cb.data = h;, as only
one of the simultaneously created nflog_handle structures is retained
due to the callback function.
Subsequently, the callback function __nflog_rcv_pkt is invoked for all
the nflog_open structures, but only references one of them.
Consequently, the callbacks registered by the end-user of the library
through nflog_callback_register fail to trigger in sessions where the
incorrect reference was recorded.
This patch corrects this behavior by creating the structure locally on
the stack for each call to nflog_open_nfnl. Since the
nfnl_callback_register function simply copies the data into its internal
structures, there is no need to retain pkt_cb beyond this point.
Signed-off-by: Evgenii Bendyak <jman.box@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'src')
-rw-r--r-- | src/libnetfilter_log.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/src/libnetfilter_log.c b/src/libnetfilter_log.c index cb09384..339c961 100644 --- a/src/libnetfilter_log.c +++ b/src/libnetfilter_log.c @@ -161,11 +161,6 @@ static int __nflog_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[], return gh->cb(gh, nfmsg, &nfldata, gh->data); } -static struct nfnl_callback pkt_cb = { - .call = &__nflog_rcv_pkt, - .attr_count = NFULA_MAX, -}; - /* public interface */ struct nfnl_handle *nflog_nfnlh(struct nflog_handle *h) @@ -255,6 +250,10 @@ struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh) { struct nflog_handle *h; int err; + struct nfnl_callback pkt_cb = { + .call = &__nflog_rcv_pkt, + .attr_count = NFULA_MAX, + }; h = calloc(1, sizeof(*h)); if (!h) |