For ABI compatibility with arm32, the compat vDSO layer on arm64 needs to return -EINVAL when UINTPTR_MAX is passed as argument to the clock_get* functions. Replace TASK_SIZE_32 with a more semantically correct formula that checks for wrapping around 0. Note: This will allow to not define TASK_SIZE_32 for the vdso headers in a future patch that will introduce asm/vdso/processor.h on arm64. Cc: Catalin Marinas <catalin.marinas@xxxxxxx> Cc: Will Deacon <will@xxxxxxxxxx> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@xxxxxxx> --- arch/arm64/kernel/vdso32/vgettimeofday.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/vdso32/vgettimeofday.c b/arch/arm64/kernel/vdso32/vgettimeofday.c index 54fc1c2ce93f..91138077b073 100644 --- a/arch/arm64/kernel/vdso32/vgettimeofday.c +++ b/arch/arm64/kernel/vdso32/vgettimeofday.c @@ -8,11 +8,14 @@ #include <linux/time.h> #include <linux/types.h> +#define VALID_CLOCK_ID(x) \ + ((x >= 0) && (x < VDSO_BASES)) + int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts) { /* The checks below are required for ABI consistency with arm */ - if ((u32)ts >= TASK_SIZE_32) + if ((u32)ts > UINTPTR_MAX - sizeof(*ts) + 1) return -EFAULT; return __cvdso_clock_gettime32(clock, ts); @@ -22,7 +25,7 @@ int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts) { /* The checks below are required for ABI consistency with arm */ - if ((u32)ts >= TASK_SIZE_32) + if ((u32)ts > UINTPTR_MAX - sizeof(*ts) + 1) return -EFAULT; return __cvdso_clock_gettime(clock, ts); @@ -38,9 +41,12 @@ int __vdso_clock_getres(clockid_t clock_id, struct old_timespec32 *res) { /* The checks below are required for ABI consistency with arm */ - if ((u32)res >= TASK_SIZE_32) + if ((u32)res > UINTPTR_MAX - sizeof(res) + 1) return -EFAULT; + if (!VALID_CLOCK_ID(clock_id) && res == NULL) + return -EINVAL; + return __cvdso_clock_getres_time32(clock_id, res); } -- 2.25.1