This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 2b0a4a20f iptables: add file lock to prevent concurrent overwrite
2b0a4a20f is described below

commit 2b0a4a20f55278461248031f5d7078520c492f50
Author: zhanghongyu <[email protected]>
AuthorDate: Wed Aug 20 20:05:59 2025 +0800

    iptables: add file lock to prevent concurrent overwrite
    
    the kernel can only prevent the concurrency of s/getsockopt, but
    iptables will call these interfaces multiple times at a time. We
    need to wait for one iptables to complete before executing the second
    one, otherwise the data will be overwritten.
    
    iptables flow:
    get current iptables entries [1] -> add new entry 2 [1,2] -> set to kernel 
[1,2]
    get current iptables entries [1] -> add new entry 3 [1,3] -> set to kernel 
[1,3]
    entry 2 is lost
    
    Signed-off-by: zhanghongyu <[email protected]>
---
 system/iptables/Kconfig    |  5 ++++
 system/iptables/iptables.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/system/iptables/Kconfig b/system/iptables/Kconfig
index 171b52ed0..a98f00771 100644
--- a/system/iptables/Kconfig
+++ b/system/iptables/Kconfig
@@ -29,4 +29,9 @@ config SYSTEM_IPTABLES_STACKSIZE
        int "iptables & ip6tables stack size"
        default DEFAULT_TASK_STACKSIZE
 
+config SYSTEM_IPTABLES_LOCK_FILE_PATH
+       string "File lock path to prevent concurrent overwrite"
+       default "/tmp/iptables.lock"
+       depends on FS_LOCK_BUCKET_SIZE > 0
+
 endif
diff --git a/system/iptables/iptables.c b/system/iptables/iptables.c
index 673559634..367519a34 100644
--- a/system/iptables/iptables.c
+++ b/system/iptables/iptables.c
@@ -26,6 +26,7 @@
 
 #include <nuttx/config.h>
 
+#include <fcntl.h>
 #include <arpa/inet.h>
 
 #include <nuttx/net/netfilter/ip_tables.h>
@@ -33,17 +34,62 @@
 #include "iptables.h"
 #include "netutils/netlib.h"
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_FS_LOCK_BUCKET_SIZE == 0
+#  define iptables_lock()     0
+#  define iptables_unlock(fd) (void)(fd)
+#endif
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 typedef CODE int
-  (*iptables_command_func_t)(FAR const struct iptables_args_s *args);
+(*iptables_command_func_t)(FAR const struct iptables_args_s *args);
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: iptables_lock / iptables_unlock
+ *
+ * Description:
+ *   Lock and unlock iptables to prevent concurrent overwrite.
+ *
+ ****************************************************************************/
+
+#if CONFIG_FS_LOCK_BUCKET_SIZE > 0
+static int iptables_lock(void)
+{
+  struct flock lock;
+  int lockfd;
+
+  lockfd = open(CONFIG_SYSTEM_IPTABLES_LOCK_FILE_PATH, O_CREAT | O_RDWR,
+                0666);
+  if (lockfd < 0)
+    {
+      return lockfd;
+    }
+
+  lock.l_type = F_WRLCK;
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0;
+  fcntl(lockfd, F_SETLKW, &lock);
+
+  return lockfd;
+}
+
+static int iptables_unlock(int lockfd)
+{
+  return close(lockfd);
+}
+#endif
+
 /****************************************************************************
  * Name: iptables_addr2str
  *
@@ -485,6 +531,7 @@ static int iptables_apply(FAR const struct iptables_args_s 
*args,
 int main(int argc, FAR char *argv[])
 {
   struct iptables_args_s args;
+  int lock;
   int ret = iptables_parse(&args, argc, argv);
 
   if (ret < 0 || args.cmd == COMMAND_INVALID)
@@ -493,6 +540,13 @@ int main(int argc, FAR char *argv[])
       return ret;
     }
 
+  lock = iptables_lock();
+  if (lock < 0)
+    {
+      printf("Failed to lock iptables!\n");
+      return lock;
+    }
+
 #ifdef CONFIG_NET_IPFILTER
   if (args.table == NULL || strcmp(args.table, XT_TABLE_NAME_FILTER) == 0)
     {
@@ -520,5 +574,7 @@ int main(int argc, FAR char *argv[])
       printf("Unknown table: %s\n", args.table);
     }
 
+  iptables_unlock(lock);
+
   return ret;
 }

Reply via email to