Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Mar 2007 09:42:46 -0500
From:      Ed Maste <emaste@phaedrus.sandvine.ca>
To:        Divacky Roman <xdivac02@stud.fit.vutbr.cz>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Hung kernel from sysv semaphore semu_list corruption
Message-ID:  <20070308144245.GA69780@sandvine.com>
In-Reply-To: <20070308095522.GA14973@stud.fit.vutbr.cz>
References:  <20070307230731.GA71684@sandvine.com> <20070308095522.GA14973@stud.fit.vutbr.cz>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 08, 2007 at 10:55:22AM +0100, Divacky Roman wrote:

> this is wrong.. you cannot remove element from a *LIST when its iterated using *LIST_FOREACH.
> Use *LIST_FOREACH_SAFE instead... 

We're not freeing the item in the loop so it would work unless
QUEUE_MACRO_DEBUG is turned on to intentionally trash the link
pointer on _REMOVE.  You're right though it's not the correct approach.
There's an efficiency issue with the previous patch anyhow in that
SLIST_REMOVE walks the list again to find the element to remove.

How about the patch below instead:

Index: sysv_sem.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/sysv_sem.c,v
retrieving revision 1.85
diff -u -r1.85 sysv_sem.c
--- sysv_sem.c  22 Oct 2006 11:52:13 -0000      1.85
+++ sysv_sem.c  8 Mar 2007 14:22:43 -0000
@@ -1301,8 +1301,10 @@
         */
        SEMUNDO_LOCK();
        SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, un_next) {
-               if (suptr->un_proc == p)
+               if (suptr->un_proc == p) {
+                       *supptr = SLIST_NEXT(suptr, un_next);
                        break;
+               }
        }
        SEMUNDO_UNLOCK();

@@ -1362,8 +1364,9 @@
         * Deallocate the undo vector.
         */
        DPRINTF(("removing vector\n"));
+       SEMUNDO_LOCK();
        suptr->un_proc = NULL;
-       *supptr = SLIST_NEXT(suptr, un_next);
+       SEMUNDO_UNLOCK();
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070308144245.GA69780>