[libnetfilter_log] fix bug in race condition of calling nflog_open from different threads at same time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.


*** a/src/libnetfilter_log.c    2024-04-30 12:45:41.974918256 +0300
--- b/src/libnetfilter_log.c    2024-04-30 12:49:56.774643783 +0300
*************** static int __nflog_rcv_pkt(struct nlmsgh
*** 161,171 ****
      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)
--- 161,166 ----
*************** struct nflog_handle *nflog_open_nfnl(str
*** 255,260 ****
--- 250,259 ----
  {
      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)




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux