From 4d4f64ffd9acc95b7c4f816a537d2c1dff8df367 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 14 Jan 2012 22:28:39 +0100 Subject: [PATCH] check the `addr` argument for PWQ_WAIT is aligned to an integer. Signed-off-by: Pierre Habouzit --- Documentation/pwqr.adoc | 3 +++ kernel/pwqr.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Documentation/pwqr.adoc b/Documentation/pwqr.adoc index 3915ed4..1942097 100644 --- a/Documentation/pwqr.adoc +++ b/Documentation/pwqr.adoc @@ -257,6 +257,9 @@ If the concurrency level is below the target, then the kernel checks if the address `addr` still contains the value `val` (in the fashion of `futex(2)`). If it doesn't then the call doesn't block. Else the calling thread is blocked until a `PWQR_WAKE` command is received. ++ +`addr` must of course be a pointer to an aligned integer which stores the +reference ticket in userland. `PWQR_PARK`:: Puts the thread in park mode. Those are spare threads to avoid diff --git a/kernel/pwqr.c b/kernel/pwqr.c index 8171596..7ce0700 100644 --- a/kernel/pwqr.c +++ b/kernel/pwqr.c @@ -368,9 +368,15 @@ do_pwqr_wait(struct pwqr_sb *sb, struct pwqr_task *pwqt, preempt_notifier_unregister(&pwqt->notifier); - if (is_wait && copy_from_user(&wait, arg, sizeof(wait))) { - rc = -EFAULT; - goto out; + if (is_wait) { + if (copy_from_user(&wait, arg, sizeof(wait))) { + rc = -EFAULT; + goto out; + } + if (unlikely((long)wait.pwqr_uaddr % sizeof(int) != 0)) { + rc = -EINVAL; + goto out; + } } pwqr_sb_lock_irqsave(sb, flags); -- 2.20.1