Skip to content

Commit 6ae40e3

Browse files
committed
posix-cpu-timers: Provide task validation functions
The code contains three slightly different copies of validating whether a given clock resolves to a valid task and whether the current caller has permissions to access it. Create central functions. Replace check_clock() as a first step and rename it to something sensible. Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent a42e43c commit 6ae40e3

File tree

1 file changed

+44
-21
lines changed

1 file changed

+44
-21
lines changed

kernel/time/posix-cpu-timers.c

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,52 @@ void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new)
3535
spin_unlock_irq(&task->sighand->siglock);
3636
}
3737

38-
static int check_clock(const clockid_t which_clock)
38+
/*
39+
* Functions for validating access to tasks.
40+
*/
41+
static struct task_struct *lookup_task(const pid_t pid, bool thread)
3942
{
40-
int error = 0;
4143
struct task_struct *p;
42-
const pid_t pid = CPUCLOCK_PID(which_clock);
4344

44-
if (CPUCLOCK_WHICH(which_clock) >= CPUCLOCK_MAX)
45-
return -EINVAL;
45+
if (!pid)
46+
return thread ? current : current->group_leader;
47+
48+
p = find_task_by_vpid(pid);
49+
if (!p || p == current)
50+
return p;
51+
if (thread)
52+
return same_thread_group(p, current) ? p : NULL;
53+
if (p == current)
54+
return p;
55+
return has_group_leader_pid(p) ? p : NULL;
56+
}
57+
58+
static struct task_struct *__get_task_for_clock(const clockid_t clock,
59+
bool getref)
60+
{
61+
const bool thread = !!CPUCLOCK_PERTHREAD(clock);
62+
const pid_t pid = CPUCLOCK_PID(clock);
63+
struct task_struct *p;
4664

47-
if (pid == 0)
48-
return 0;
65+
if (CPUCLOCK_WHICH(clock) >= CPUCLOCK_MAX)
66+
return NULL;
4967

5068
rcu_read_lock();
51-
p = find_task_by_vpid(pid);
52-
if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
53-
same_thread_group(p, current) : has_group_leader_pid(p))) {
54-
error = -EINVAL;
55-
}
69+
p = lookup_task(pid, thread);
70+
if (p && getref)
71+
get_task_struct(p);
5672
rcu_read_unlock();
73+
return p;
74+
}
5775

58-
return error;
76+
static inline struct task_struct *get_task_for_clock(const clockid_t clock)
77+
{
78+
return __get_task_for_clock(clock, true);
79+
}
80+
81+
static inline int validate_clock_permissions(const clockid_t clock)
82+
{
83+
return __get_task_for_clock(clock, false) ? 0 : -EINVAL;
5984
}
6085

6186
/*
@@ -125,7 +150,8 @@ static inline u64 virt_ticks(struct task_struct *p)
125150
static int
126151
posix_cpu_clock_getres(const clockid_t which_clock, struct timespec64 *tp)
127152
{
128-
int error = check_clock(which_clock);
153+
int error = validate_clock_permissions(which_clock);
154+
129155
if (!error) {
130156
tp->tv_sec = 0;
131157
tp->tv_nsec = ((NSEC_PER_SEC + HZ - 1) / HZ);
@@ -142,20 +168,17 @@ posix_cpu_clock_getres(const clockid_t which_clock, struct timespec64 *tp)
142168
}
143169

144170
static int
145-
posix_cpu_clock_set(const clockid_t which_clock, const struct timespec64 *tp)
171+
posix_cpu_clock_set(const clockid_t clock, const struct timespec64 *tp)
146172
{
173+
int error = validate_clock_permissions(clock);
174+
147175
/*
148176
* You can never reset a CPU clock, but we check for other errors
149177
* in the call before failing with EPERM.
150178
*/
151-
int error = check_clock(which_clock);
152-
if (error == 0) {
153-
error = -EPERM;
154-
}
155-
return error;
179+
return error ? : -EPERM;
156180
}
157181

158-
159182
/*
160183
* Sample a per-thread clock for the given task.
161184
*/

0 commit comments

Comments
 (0)