From 4758ebb5cda3e97eaaa22fb4049484d6ff9f0764 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 6 Dec 2022 06:44:06 -0500 Subject: [PATCH] Fixes for 5.4 Signed-off-by: Sasha Levin --- ...ling-sem_array-access-in-semtimedop-.patch | 75 +++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 76 insertions(+) create mode 100644 queue-5.4/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch diff --git a/queue-5.4/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch b/queue-5.4/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch new file mode 100644 index 00000000000..33d304435f5 --- /dev/null +++ b/queue-5.4/ipc-sem-fix-dangling-sem_array-access-in-semtimedop-.patch @@ -0,0 +1,75 @@ +From 477940c0105505e33186436461b85bd55b97067a 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 bd907ed2ce00..31cfe0f5fa8d 100644 +--- a/ipc/sem.c ++++ b/ipc/sem.c +@@ -2171,6 +2171,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) { + /* +@@ -2180,10 +2181,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-5.4/series b/queue-5.4/series index 7d31e7b3f1e..d90195da98f 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -154,3 +154,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 -- 2.47.3