From: Sasha Levin Date: Tue, 6 Dec 2022 11:44:07 +0000 (-0500) Subject: Fixes for 4.14 X-Git-Tag: v4.9.335~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fae589db7a848aada686525ce22c5474893727ab;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.14 Signed-off-by: Sasha Levin --- diff --git a/queue-4.14/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch b/queue-4.14/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch new file mode 100644 index 00000000000..0b6cdce1f38 --- /dev/null +++ b/queue-4.14/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch @@ -0,0 +1,75 @@ +From 94604de3a297eb3137d3fbc8e0b4b87aee7b7f1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 17:59:27 +0100 +Subject: ipc/sem: Fix dangling sem_array access in semtimedop race + +From: Jann Horn + +[ Upstream commit b52be557e24c47286738276121177a41f54e3b83 ] + +When __do_semtimedop() goes to sleep because it has to wait for a +semaphore value becoming zero or becoming bigger than some threshold, it +links the on-stack sem_queue to the sem_array, then goes to sleep +without holding a reference on the sem_array. + +When __do_semtimedop() comes back out of sleep, one of two things must +happen: + + a) We prove that the on-stack sem_queue has been disconnected from the + (possibly freed) sem_array, making it safe to return from the stack + frame that the sem_queue exists in. + + b) We stabilize our reference to the sem_array, lock the sem_array, and + detach the sem_queue from the sem_array ourselves. + +sem_array has RCU lifetime, so for case (b), the reference can be +stabilized inside an RCU read-side critical section by locklessly +checking whether the sem_queue is still connected to the sem_array. + +However, the current code does the lockless check on sem_queue before +starting an RCU read-side critical section, so the result of the +lockless check immediately becomes useless. + +Fix it by doing rcu_read_lock() before the lockless check. Now RCU +ensures that if we observe the object being on our queue, the object +can't be freed until rcu_read_unlock(). + +This bug is only hittable on kernel builds with full preemption support +(either CONFIG_PREEMPT or PREEMPT_DYNAMIC with preempt=full). + +Fixes: 370b262c896e ("ipc/sem: avoid idr tree lookup for interrupted semop") +Cc: stable@vger.kernel.org +Signed-off-by: Jann Horn +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + ipc/sem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ipc/sem.c b/ipc/sem.c +index 6adc245f3e02..89fef4550b38 100644 +--- a/ipc/sem.c ++++ b/ipc/sem.c +@@ -2064,6 +2064,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, + * scenarios where we were awakened externally, during the + * window between wake_q_add() and wake_up_q(). + */ ++ rcu_read_lock(); + error = READ_ONCE(queue.status); + if (error != -EINTR) { + /* +@@ -2073,10 +2074,10 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, + * overwritten by the previous owner of the semaphore. + */ + smp_mb(); ++ rcu_read_unlock(); + goto out_free; + } + +- rcu_read_lock(); + locknum = sem_lock(sma, sops, nsops); + + if (!ipc_valid_object(&sma->sem_perm)) +-- +2.35.1 + diff --git a/queue-4.14/series b/queue-4.14/series index e59a31eebc9..5f20d382bb4 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -78,3 +78,4 @@ mmc-sdhci-fix-voltage-switch-delay.patch proc-avoid-integer-type-confusion-in-get_proc_long.patch proc-proc_skip_spaces-shouldn-t-think-it-is-working-on-c-strings.patch v4l2-don-t-fall-back-to-follow_pfn-if-pin_user_pages_fast-fails.patch +ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch