X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=ipc%2Fsem.c;h=b31c3ef43c913f4cea4d583703ea015c9c777a2f;hp=5215a81420df9b1802dd9f6c40c465f1b63a2bbd;hb=f63b2b3204ea962e9cc34a223771ec973694f8bf;hpb=b4949b84567f3ae1227d076fc95bbd8efea06506 diff --git a/ipc/sem.c b/ipc/sem.c index 5215a81420df..b31c3ef43c91 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -314,14 +314,6 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) return retval; } - id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); - if (id < 0) { - security_sem_free(sma); - ipc_rcu_putref(sma); - return id; - } - ns->used_sems += nsems; - sma->sem_base = (struct sem *) &sma[1]; for (i = 0; i < nsems; i++) @@ -332,6 +324,15 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) INIT_LIST_HEAD(&sma->list_id); sma->sem_nsems = nsems; sma->sem_ctime = get_seconds(); + + id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); + if (id < 0) { + security_sem_free(sma); + ipc_rcu_putref(sma); + return id; + } + ns->used_sems += nsems; + sem_unlock(sma); return sma->sem_perm.id; @@ -1606,16 +1607,27 @@ void exit_sem(struct task_struct *tsk) rcu_read_lock(); un = list_entry_rcu(ulp->list_proc.next, struct sem_undo, list_proc); - if (&un->list_proc == &ulp->list_proc) - semid = -1; - else - semid = un->semid; + if (&un->list_proc == &ulp->list_proc) { + /* + * We must wait for freeary() before freeing this ulp, + * in case we raced with last sem_undo. There is a small + * possibility where we exit while freeary() didn't + * finish unlocking sem_undo_list. + */ + spin_unlock_wait(&ulp->lock); + rcu_read_unlock(); + break; + } + spin_lock(&ulp->lock); + semid = un->semid; + spin_unlock(&ulp->lock); rcu_read_unlock(); + /* exit_sem raced with IPC_RMID, nothing to do */ if (semid == -1) - break; + continue; - sma = sem_lock_check(tsk->nsproxy->ipc_ns, un->semid); + sma = sem_lock_check(tsk->nsproxy->ipc_ns, semid); /* exit_sem raced with IPC_RMID, nothing to do */ if (IS_ERR(sma))