summaryrefslogtreecommitdiff
path: root/kernel/time/posix-timers.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-02-15 16:21:55 (GMT)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>2019-04-23 16:15:57 (GMT)
commiteb4a3a43d161cc361b0983f198136fe5a4aac425 (patch)
tree8b2bd17b22fd79b02fccbff59cb6f4b1cc209257 /kernel/time/posix-timers.c
parent7da95efa7342ff3d8f732cb25b85b55e5fc6a75a (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.c11
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)