HI all,

Try the following:

-create a semaphore
-create a task
-let the task wait on the semaphore, no timeout
-delete the task
-delete the semaphore -> oops

The problem:

rt_task_ipc_deletes unlinks the task from the semaphores wait list, but
doesn't up the value of the semaphore

rt_sem_destroy sees a val < 0 and thus posts an event, this post then
finds nothing in the list, but it wants to run something since val < 0
so it runs nothing (NULL ptr) ->  oops.

So this could be reconstructed too by:
-create semaphore
-create task
-lett task wait on semaphore
-delete task
-post to semaphore -> oops

I noticed another problem where a wait with timeout wouldn't clear the
sem_at member of the semaphore and a possible race on process deletion.

Attached is a patch fixing all these, please apply for those still using
rt_ipc.

Regards,

Hans
--- rtlinux-2.2/semaphores/rt_ipc.c.semfix      Tue Dec  5 13:03:35 2000
+++ rtlinux-2.2/semaphores/rt_ipc.c     Tue Dec  5 17:13:24 2000
@@ -231,6 +231,7 @@
           {
             /* timeout occurred -- undo everything and return */
             unlink_sem_task(to_add, sem);
+            ((RT_TASK_IPC *)rtl_current)->sem_at = NULL;
             ++sem->val;
             ret = -ETIME;
           }
@@ -319,10 +320,18 @@
   {
     /* for task deletion safety, must remove task from any sem or mq list */
     int flags;
+    
+    /* suspend thread to make sure it doesn't timeout on a
+       semaphore wait after it has already been unlinked from
+       the sem linked list, but before it is deleted */
+    rt_task_suspend(MAKE_RT_TASK(task));
 
     rtl_critical(flags);
     if (task->sem_at != NULL)
+    {
       unlink_sem_task(&(task->rte), task->sem_at);
+      task->sem_at->val++;
+    }
     else if (task->mq_at != NULL)
       unlink_mq_task(&(task->rte), task->mq_at);
     rtl_end_critical(flags);

Reply via email to