lib: fdtable: fix z_free_fd multiple calls fd leak
Multiple calls of z_free_fd against fd with refcount equal 0 are causing
descriptor table entry leak by decrementing refcount below 0.
This patch prevents decrementing refcount below zero.
Signed-off-by: Grzegorz Kostka <grzegorz@mobility.cloud>
diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c
index 8e6de5a..2839ed4 100644
--- a/lib/os/fdtable.c
+++ b/lib/os/fdtable.c
@@ -63,7 +63,19 @@
static int z_fd_unref(int fd)
{
- int old_rc = atomic_dec(&fdtable[fd].refcount);
+ atomic_val_t old_rc;
+
+ /* Reference counter must be checked to avoid decrement refcount below
+ * zero causing file descriptor leak. Loop statement below executes
+ * atomic decrement if refcount value is grater than zero. Otherwise,
+ * refcount is not going to be written.
+ */
+ do {
+ old_rc = atomic_get(&fdtable[fd].refcount);
+ if (!old_rc) {
+ return 0;
+ }
+ } while (!atomic_cas(&fdtable[fd].refcount, old_rc, old_rc - 1));
if (old_rc != 1) {
return old_rc - 1;