summaryrefslogtreecommitdiffstats
path: root/ipc/sem.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2018-07-23 15:21:39 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2018-07-23 15:21:39 +1000
commitd5e748ff2b996d83489ac76c072e8b99f9ecef13 (patch)
treee2dfdf187d2200898be728b97a31843f3fc26808 /ipc/sem.c
parentfea9cf321c916e9372874e6f2af1bf0b5beb89fb (diff)
parenta7ca13826e478f9b201eb2f9f20de0b978a82ad9 (diff)
downloadtalos-op-linux-d5e748ff2b996d83489ac76c072e8b99f9ecef13.tar.gz
talos-op-linux-d5e748ff2b996d83489ac76c072e8b99f9ecef13.zip
Merge remote-tracking branch 'gpio/ib-aspeed' into upstream-ready
Merge the GPIO tree "ib-aspeed" topic branch which contains pre-requisites for subsequent changes. This branch is also in gpio "next".
Diffstat (limited to 'ipc/sem.c')
-rw-r--r--ipc/sem.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index cfd94d48a9aa..5af1943ad782 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -85,6 +85,7 @@
#include <linux/nsproxy.h>
#include <linux/ipc_namespace.h>
#include <linux/sched/wake_q.h>
+#include <linux/nospec.h>
#include <linux/uaccess.h>
#include "util.h"
@@ -368,6 +369,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
int nsops)
{
struct sem *sem;
+ int idx;
if (nsops != 1) {
/* Complex operation - acquire a full lock */
@@ -385,7 +387,8 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
*
* Both facts are tracked by use_global_mode.
*/
- sem = &sma->sems[sops->sem_num];
+ idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
+ sem = &sma->sems[idx];
/*
* Initial check for use_global_lock. Just an optimization,
@@ -638,7 +641,8 @@ static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q)
un = q->undo;
for (sop = sops; sop < sops + nsops; sop++) {
- curr = &sma->sems[sop->sem_num];
+ int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
+ curr = &sma->sems[idx];
sem_op = sop->sem_op;
result = curr->semval;
@@ -718,7 +722,9 @@ static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q)
* until the operations can go through.
*/
for (sop = sops; sop < sops + nsops; sop++) {
- curr = &sma->sems[sop->sem_num];
+ int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
+
+ curr = &sma->sems[idx];
sem_op = sop->sem_op;
result = curr->semval;
@@ -1356,6 +1362,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
return -EIDRM;
}
+ semnum = array_index_nospec(semnum, sma->sem_nsems);
curr = &sma->sems[semnum];
ipc_assert_locked_object(&sma->sem_perm);
@@ -1509,6 +1516,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
err = -EIDRM;
goto out_unlock;
}
+
+ semnum = array_index_nospec(semnum, nsems);
curr = &sma->sems[semnum];
switch (cmd) {
@@ -1945,7 +1954,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
if (nsops > ns->sc_semopm)
return -E2BIG;
if (nsops > SEMOPM_FAST) {
- sops = kvmalloc(sizeof(*sops)*nsops, GFP_KERNEL);
+ sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL);
if (sops == NULL)
return -ENOMEM;
}
@@ -2081,7 +2090,8 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
*/
if (nsops == 1) {
struct sem *curr;
- curr = &sma->sems[sops->sem_num];
+ int idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
+ curr = &sma->sems[idx];
if (alter) {
if (sma->complex_count) {
OpenPOWER on IntegriCloud