aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/sem.c
diff options
context:
space:
mode:
authorNadia Derbey <Nadia.Derbey@bull.net>2007-10-19 02:40:51 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 14:53:44 -0400
commit023a53557ea0e987b002e9a844242ef0b0aa1eb3 (patch)
tree7f3accdd7cb1d801607bf71e56b9b99e9c7ff7ca /ipc/sem.c
parent637c36634029e4e7c81112796dafc32d56355b4a (diff)
ipc: integrate ipc_checkid() into ipc_lock()
This patch introduces a new ipc_lock_check() routine interface: . each time ipc_checkid() is called, this is done after calling ipc_lock(). ipc_checkid() is now called from inside ipc_lock_check(). [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix RCU locking] Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/sem.c')
-rw-r--r--ipc/sem.c70
1 files changed, 33 insertions, 37 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 6af226af0b90..673d63da52c6 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -88,7 +88,6 @@
88 88
89#define sem_ids(ns) (*((ns)->ids[IPC_SEM_IDS])) 89#define sem_ids(ns) (*((ns)->ids[IPC_SEM_IDS]))
90 90
91#define sem_lock(ns, id) ((struct sem_array*)ipc_lock(&sem_ids(ns), id))
92#define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm) 91#define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm)
93#define sem_checkid(ns, sma, semid) \ 92#define sem_checkid(ns, sma, semid) \
94 ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid) 93 ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
@@ -175,6 +174,17 @@ void __init sem_init (void)
175 IPC_SEM_IDS, sysvipc_sem_proc_show); 174 IPC_SEM_IDS, sysvipc_sem_proc_show);
176} 175}
177 176
177static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
178{
179 return (struct sem_array *) ipc_lock(&sem_ids(ns), id);
180}
181
182static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns,
183 int id)
184{
185 return (struct sem_array *) ipc_lock_check(&sem_ids(ns), id);
186}
187
178static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) 188static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
179{ 189{
180 ipc_rmid(&sem_ids(ns), &s->sem_perm); 190 ipc_rmid(&sem_ids(ns), &s->sem_perm);
@@ -599,11 +609,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
599 struct semid64_ds tbuf; 609 struct semid64_ds tbuf;
600 int id; 610 int id;
601 611
602 memset(&tbuf,0,sizeof(tbuf));
603
604 sma = sem_lock(ns, semid); 612 sma = sem_lock(ns, semid);
605 if(sma == NULL) 613 if (IS_ERR(sma))
606 return -EINVAL; 614 return PTR_ERR(sma);
607 615
608 err = -EACCES; 616 err = -EACCES;
609 if (ipcperms (&sma->sem_perm, S_IRUGO)) 617 if (ipcperms (&sma->sem_perm, S_IRUGO))
@@ -615,6 +623,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
615 623
616 id = sma->sem_perm.id; 624 id = sma->sem_perm.id;
617 625
626 memset(&tbuf, 0, sizeof(tbuf));
627
618 kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); 628 kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
619 tbuf.sem_otime = sma->sem_otime; 629 tbuf.sem_otime = sma->sem_otime;
620 tbuf.sem_ctime = sma->sem_ctime; 630 tbuf.sem_ctime = sma->sem_ctime;
@@ -643,16 +653,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
643 ushort* sem_io = fast_sem_io; 653 ushort* sem_io = fast_sem_io;
644 int nsems; 654 int nsems;
645 655
646 sma = sem_lock(ns, semid); 656 sma = sem_lock_check(ns, semid);
647 if(sma==NULL) 657 if (IS_ERR(sma))
648 return -EINVAL; 658 return PTR_ERR(sma);
649 659
650 nsems = sma->sem_nsems; 660 nsems = sma->sem_nsems;
651 661
652 err=-EIDRM;
653 if (sem_checkid(ns,sma,semid))
654 goto out_unlock;
655
656 err = -EACCES; 662 err = -EACCES;
657 if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO)) 663 if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO))
658 goto out_unlock; 664 goto out_unlock;
@@ -864,14 +870,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
864 if(copy_semid_from_user (&setbuf, arg.buf, version)) 870 if(copy_semid_from_user (&setbuf, arg.buf, version))
865 return -EFAULT; 871 return -EFAULT;
866 } 872 }
867 sma = sem_lock(ns, semid); 873 sma = sem_lock_check(ns, semid);
868 if(sma==NULL) 874 if (IS_ERR(sma))
869 return -EINVAL; 875 return PTR_ERR(sma);
870 876
871 if (sem_checkid(ns,sma,semid)) {
872 err=-EIDRM;
873 goto out_unlock;
874 }
875 ipcp = &sma->sem_perm; 877 ipcp = &sma->sem_perm;
876 878
877 err = audit_ipc_obj(ipcp); 879 err = audit_ipc_obj(ipcp);
@@ -1055,15 +1057,10 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
1055 goto out; 1057 goto out;
1056 1058
1057 /* no undo structure around - allocate one. */ 1059 /* no undo structure around - allocate one. */
1058 sma = sem_lock(ns, semid); 1060 sma = sem_lock_check(ns, semid);
1059 un = ERR_PTR(-EINVAL); 1061 if (IS_ERR(sma))
1060 if(sma==NULL) 1062 return ERR_PTR(PTR_ERR(sma));
1061 goto out; 1063
1062 un = ERR_PTR(-EIDRM);
1063 if (sem_checkid(ns,sma,semid)) {
1064 sem_unlock(sma);
1065 goto out;
1066 }
1067 nsems = sma->sem_nsems; 1064 nsems = sma->sem_nsems;
1068 ipc_rcu_getref(sma); 1065 ipc_rcu_getref(sma);
1069 sem_unlock(sma); 1066 sem_unlock(sma);
@@ -1169,15 +1166,14 @@ retry_undos:
1169 } else 1166 } else
1170 un = NULL; 1167 un = NULL;
1171 1168
1172 sma = sem_lock(ns, semid); 1169 sma = sem_lock_check(ns, semid);
1173 error=-EINVAL; 1170 if (IS_ERR(sma)) {
1174 if(sma==NULL) 1171 error = PTR_ERR(sma);
1175 goto out_free; 1172 goto out_free;
1176 error = -EIDRM; 1173 }
1177 if (sem_checkid(ns,sma,semid)) 1174
1178 goto out_unlock_free;
1179 /* 1175 /*
1180 * semid identifies are not unique - find_undo may have 1176 * semid identifiers are not unique - find_undo may have
1181 * allocated an undo structure, it was invalidated by an RMID 1177 * allocated an undo structure, it was invalidated by an RMID
1182 * and now a new array with received the same id. Check and retry. 1178 * and now a new array with received the same id. Check and retry.
1183 */ 1179 */
@@ -1243,7 +1239,7 @@ retry_undos:
1243 } 1239 }
1244 1240
1245 sma = sem_lock(ns, semid); 1241 sma = sem_lock(ns, semid);
1246 if(sma==NULL) { 1242 if (IS_ERR(sma)) {
1247 BUG_ON(queue.prev != NULL); 1243 BUG_ON(queue.prev != NULL);
1248 error = -EIDRM; 1244 error = -EIDRM;
1249 goto out_free; 1245 goto out_free;
@@ -1343,7 +1339,7 @@ void exit_sem(struct task_struct *tsk)
1343 if(semid == -1) 1339 if(semid == -1)
1344 continue; 1340 continue;
1345 sma = sem_lock(ns, semid); 1341 sma = sem_lock(ns, semid);
1346 if (sma == NULL) 1342 if (IS_ERR(sma))
1347 continue; 1343 continue;
1348 1344
1349 if (u->semid == -1) 1345 if (u->semid == -1)