diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-02-15 16:21:55 (GMT) |
|---|---|---|
| committer | Kleber Sacilotto de Souza <kleber.souza@canonical.com> | 2019-04-23 16:15:57 (GMT) |
| commit | eb4a3a43d161cc361b0983f198136fe5a4aac425 (patch) | |
| tree | 8b2bd17b22fd79b02fccbff59cb6f4b1cc209257 /kernel/time/posix-timers.c | |
| parent | 7da95efa7342ff3d8f732cb25b85b55e5fc6a75a (diff) | |
posix-timers: Protect posix clock array access against speculation
The clockid argument of clockid_to_kclock() comes straight from user space
via various syscalls and is used as index into the posix_clocks array.
Protect it against spectre v1 array out of bounds speculation. Remove the
redundant check for !posix_clock[id] as this is another source for
speculation and does not provide any advantage over the return
posix_clock[id] path which returns NULL in that case anyway.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Cc: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1802151718320.1296@nanos.tec.linutronix.de
CVE-2017-5753
(backported from commit 19b558db12f9f4e45a22012bae7b4783e62224da)
[juergh: Context adjustments.]
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Diffstat (limited to 'kernel/time/posix-timers.c')
| -rw-r--r-- | kernel/time/posix-timers.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index d59e458..fef1315 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -48,6 +48,7 @@ #include <linux/workqueue.h> #include <linux/export.h> #include <linux/hashtable.h> +#include <linux/nospec.h> #include "timekeeping.h" @@ -595,13 +596,17 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) static struct k_clock *clockid_to_kclock(const clockid_t id) { - if (id < 0) + clockid_t idx = id; + + if (id < 0) { return (id & CLOCKFD_MASK) == CLOCKFD ? &clock_posix_dynamic : &clock_posix_cpu; + } - if (id >= MAX_CLOCKS || !posix_clocks[id].clock_getres) + if (id >= MAX_CLOCKS) return NULL; - return &posix_clocks[id]; + + return &posix_clocks[array_index_nospec(idx, MAX_CLOCKS)]; } static int common_timer_create(struct k_itimer *new_timer) |
