projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[firefly-linux-kernel-4.4.55.git]
/
ipc
/
sem.c
diff --git
a/ipc/sem.c
b/ipc/sem.c
index 8c4f59b0204a2821811a4b28fd48e0ce6163d987..db9d241af133d770cb0a95a22cacf257f79b1215 100644
(file)
--- a/
ipc/sem.c
+++ b/
ipc/sem.c
@@
-1282,6
+1282,12
@@
static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
sem_lock(sma, NULL, -1);
sem_lock(sma, NULL, -1);
+ if (sma->sem_perm.deleted) {
+ sem_unlock(sma, -1);
+ rcu_read_unlock();
+ return -EIDRM;
+ }
+
curr = &sma->sem_base[semnum];
ipc_assert_locked_object(&sma->sem_perm);
curr = &sma->sem_base[semnum];
ipc_assert_locked_object(&sma->sem_perm);
@@
-1336,12
+1342,14
@@
static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
int i;
sem_lock(sma, NULL, -1);
int i;
sem_lock(sma, NULL, -1);
+ if (sma->sem_perm.deleted) {
+ err = -EIDRM;
+ goto out_unlock;
+ }
if(nsems > SEMMSL_FAST) {
if (!ipc_rcu_getref(sma)) {
if(nsems > SEMMSL_FAST) {
if (!ipc_rcu_getref(sma)) {
- sem_unlock(sma, -1);
- rcu_read_unlock();
err = -EIDRM;
err = -EIDRM;
- goto out_
free
;
+ goto out_
unlock
;
}
sem_unlock(sma, -1);
rcu_read_unlock();
}
sem_unlock(sma, -1);
rcu_read_unlock();
@@
-1354,10
+1362,8
@@
static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
rcu_read_lock();
sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
rcu_read_lock();
sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
- sem_unlock(sma, -1);
- rcu_read_unlock();
err = -EIDRM;
err = -EIDRM;
- goto out_
free
;
+ goto out_
unlock
;
}
}
for (i = 0; i < sma->sem_nsems; i++)
}
}
for (i = 0; i < sma->sem_nsems; i++)
@@
-1375,8
+1381,8
@@
static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
struct sem_undo *un;
if (!ipc_rcu_getref(sma)) {
struct sem_undo *un;
if (!ipc_rcu_getref(sma)) {
-
rcu_read_unlock()
;
-
return -EIDRM
;
+
err = -EIDRM
;
+
goto out_rcu_wakeup
;
}
rcu_read_unlock();
}
rcu_read_unlock();
@@
-1404,10
+1410,8
@@
static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
rcu_read_lock();
sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
rcu_read_lock();
sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
- sem_unlock(sma, -1);
- rcu_read_unlock();
err = -EIDRM;
err = -EIDRM;
- goto out_
free
;
+ goto out_
unlock
;
}
for (i = 0; i < nsems; i++)
}
for (i = 0; i < nsems; i++)
@@
-1431,6
+1435,10
@@
static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
goto out_rcu_wakeup;
sem_lock(sma, NULL, -1);
goto out_rcu_wakeup;
sem_lock(sma, NULL, -1);
+ if (sma->sem_perm.deleted) {
+ err = -EIDRM;
+ goto out_unlock;
+ }
curr = &sma->sem_base[semnum];
switch (cmd) {
curr = &sma->sem_base[semnum];
switch (cmd) {
@@
-1836,6
+1844,10
@@
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
if (error)
goto out_rcu_wakeup;
if (error)
goto out_rcu_wakeup;
+ error = -EIDRM;
+ locknum = sem_lock(sma, sops, nsops);
+ if (sma->sem_perm.deleted)
+ goto out_unlock_free;
/*
* semid identifiers are not unique - find_alloc_undo may have
* allocated an undo structure, it was invalidated by an RMID
/*
* semid identifiers are not unique - find_alloc_undo may have
* allocated an undo structure, it was invalidated by an RMID
@@
-1843,8
+1855,6
@@
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
* This case can be detected checking un->semid. The existence of
* "un" itself is guaranteed by rcu.
*/
* This case can be detected checking un->semid. The existence of
* "un" itself is guaranteed by rcu.
*/
- error = -EIDRM;
- locknum = sem_lock(sma, sops, nsops);
if (un && un->semid == -1)
goto out_unlock_free;
if (un && un->semid == -1)
goto out_unlock_free;
@@
-2057,6
+2067,12
@@
void exit_sem(struct task_struct *tsk)
}
sem_lock(sma, NULL, -1);
}
sem_lock(sma, NULL, -1);
+ /* exit_sem raced with IPC_RMID, nothing to do */
+ if (sma->sem_perm.deleted) {
+ sem_unlock(sma, -1);
+ rcu_read_unlock();
+ continue;
+ }
un = __lookup_undo(ulp, semid);
if (un == NULL) {
/* exit_sem raced with IPC_RMID+semget() that created
un = __lookup_undo(ulp, semid);
if (un == NULL) {
/* exit_sem raced with IPC_RMID+semget() that created