check the `addr` argument for PWQ_WAIT is aligned to an integer.
authorPierre Habouzit <pierre.habouzit@intersec.com>
Sat, 14 Jan 2012 21:28:39 +0000 (22:28 +0100)
committerPierre Habouzit <pierre.habouzit@intersec.com>
Sat, 14 Jan 2012 21:29:36 +0000 (22:29 +0100)
Signed-off-by: Pierre Habouzit <pierre.habouzit@intersec.com>
Documentation/pwqr.adoc
kernel/pwqr.c

index 3915ed4..1942097 100644 (file)
@@ -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.
 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
 
 `PWQR_PARK`::
        Puts the thread in park mode. Those are spare threads to avoid
index 8171596..7ce0700 100644 (file)
@@ -368,9 +368,15 @@ do_pwqr_wait(struct pwqr_sb *sb, struct pwqr_task *pwqt,
 
        preempt_notifier_unregister(&pwqt->notifier);
 
 
        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);
        }
 
        pwqr_sb_lock_irqsave(sb, flags);