bug-hurd
[Top][All Lists]
Advanced

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

[PATCH 1/1] procfs: Fix use-after-free


From: Sergey Bugaev
Subject: [PATCH 1/1] procfs: Fix use-after-free
Date: Mon, 24 May 2021 18:43:40 +0300

Fix several issues with reference counting in
rootdir_make_translated_node ():

* Grab an additional reference while still holding the lock.

* Give the node an additional reference for being pointed to
  by the ops.

* Reference the existing node if we find it on the second try,
  not only if we find it on the first try.

* Dereference, not just clean, the created node if it turns out
  to be unneeded.

Fixes a crash with the following backtrace:

 #2  0x010855c8 in __assert_fail_backtrace (
     assertion=0x1051148 "! (r.hard == 1 && r.weak == 0) || !\"refcount 
detected use-after-free!\"",
     file=0x1050cec "../../libshouldbeinlibc/refcount.h", line=170, 
function=0x1051220 <__PRETTY_FUNCTION__.3> "refcounts_ref")
     at ../../libshouldbeinlibc/assert-backtrace.c:64
 #3  0x01050358 in refcounts_ref (result=0x0, ref=0x15009a0) at 
../../libshouldbeinlibc/refcount.h:170
 #4  netfs_nref (np=0x15008f0) at ../../libnetfs/nref.c:26
 #5  0x0804c9f4 in rootdir_make_translated_node (dir_hook=0x10001990, 
entry_hook=0x8055180 <__compound_literal.8>)
     at ../../procfs/rootdir.c:674
 #6  0x0804ace3 in procfs_dir_lookup (hook=0x10001c10, name=0x2857efc "mounts", 
np=0x2855d68) at ../../procfs/procfs_dir.c:88
 #7  0x0804a410 in procfs_lookup (np=0x10001c40, name=0x2857efc "mounts", 
npp=0x2855d68) at ../../procfs/procfs.c:185
 #8  0x0804cae5 in dircat_lookup (hook=0x10001d50, name=0x2857efc "mounts", 
np=0x2855d68) at ../../procfs/dircat.c:76
 #9  0x0804a410 in procfs_lookup (np=0x10001d80, name=0x2857efc "mounts", 
npp=0x2855d68) at ../../procfs/procfs.c:185
 #10 0x0804a96f in netfs_attempt_lookup (user=0x1401c60, dir=0x10001d80, 
name=0x2857efc "mounts", np=0x2855d68)
     at ../../procfs/netfs.c:212
 #11 0x0103fd5b in netfs_S_dir_lookup (dircred=<optimized out>, 
filename=<optimized out>, flags=<optimized out>,
     mode=<optimized out>, do_retry=<optimized out>, retry_name=<optimized 
out>, retry_port=<optimized out>,
     retry_port_type=<optimized out>) at ../../libnetfs/dir-lookup.c:175
---
 procfs/rootdir.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/procfs/rootdir.c b/procfs/rootdir.c
index 9f860a91..0e7c05c0 100644
--- a/procfs/rootdir.c
+++ b/procfs/rootdir.c
@@ -667,13 +667,12 @@ rootdir_make_translated_node (void *dir_hook, const void 
*entry_hook)
 
   pthread_spin_lock (&rootdir_translated_node_lock);
   np = *ops->npp;
+  if (np != NULL)
+    netfs_nref (np);
   pthread_spin_unlock (&rootdir_translated_node_lock);
 
   if (np != NULL)
-    {
-      netfs_nref (np);
-      return np;
-    }
+    return np;
 
   np = procfs_make_node (entry_hook, (void *) entry_hook);
   if (np == NULL)
@@ -686,11 +685,12 @@ rootdir_make_translated_node (void *dir_hook, const void 
*entry_hook)
   prev = *ops->npp;
   if (*ops->npp == NULL)
     *ops->npp = np;
+  netfs_nref (*ops->npp);
   pthread_spin_unlock (&rootdir_translated_node_lock);
 
   if (prev != NULL)
     {
-      procfs_cleanup (np);
+      netfs_nrele (np);
       np = prev;
     }
 
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]