Returning -EINVAL when a permission check fails is not really intuitive and
can cause hard to diagnose problems.

The POSIX specification for clock_gettime() and timer_create() requires to
obtain the clock id first by invoking clock_getcpuclockid().

clock_getcpuclockid() can return -EPERM if the caller does not have
permissions. That does not make sense in two aspects:

 - Nothing prevents the caller to make up a clockid and feed it into the
   syscalls

 - clock_getcpuclockid() is a helper function in glibc which just mangles
   the PID/TID bits to the proper place and glibc cannot do any permission
   checks at all for this function.

In order to prevent abuse the kernel has to do the permission checking in
timer_create() and clock_gettime(). Those functions have only -EINVAL as
documented return values, but returning -EINVAL for a valid clockid when
the permission check fails is not understandable for programmers.

So ignore the POSIX specification and return -EPERM when the ptrace
permission check fails.

Suggested-by: Peter Zijlstra <pet...@infradead.org>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
V2: New patch.

TODO: Update timer_create.2 and clock_gettime.2 manpages
---
 kernel/time/posix-cpu-timers.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -107,7 +107,7 @@ static struct task_struct *lookup_task(c
        }
 
        /* Decide based on the ptrace permissions. */
-       return ptrace_may_access(p, mode) ? p : ERR_PTR(-EINVAL);
+       return ptrace_may_access(p, mode) ? p : ERR_PTR(-EPERM);
 }
 
 static struct task_struct *__get_task_for_clock(const clockid_t clock,


Reply via email to