diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/core.c | 15 | ||||
| -rw-r--r-- | kernel/exit.c | 5 | ||||
| -rw-r--r-- | kernel/fork.c | 2 | ||||
| -rw-r--r-- | kernel/sched/core.c | 32 |
4 files changed, 52 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index f06d8db54db..70cdda89939 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6143,7 +6143,6 @@ skip_type: __perf_event_init_context(&cpuctx->ctx); lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); - cpuctx->ctx.type = cpu_context; cpuctx->ctx.pmu = pmu; cpuctx->jiffies_interval = 1; INIT_LIST_HEAD(&cpuctx->rotation_list); @@ -6783,7 +6782,19 @@ SYSCALL_DEFINE5(perf_event_open, * task or CPU context: */ if (move_group) { - if (group_leader->ctx->type != ctx->type) + /* + * Make sure we're both on the same task, or both + * per-cpu events. + */ + if (group_leader->ctx->task != ctx->task) + goto err_context; + + /* + * Make sure we're both events for the same CPU; + * grouping events for different CPUs is broken; since + * you can never concurrently schedule them anyhow. + */ + if (group_leader->cpu != event->cpu) goto err_context; } else { if (group_leader->ctx != ctx) diff --git a/kernel/exit.c b/kernel/exit.c index f28427b2f95..3eafd262e52 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -957,6 +957,11 @@ void do_exit(long code) } exit_signals(tsk); /* sets PF_EXITING */ + + if (tsk->flags & PF_SU) { + su_exit(); + } + /* * tsk->flags are checked in the futex code to protect against * an exiting task cleaning up the robust pi futexes. diff --git a/kernel/fork.c b/kernel/fork.c index 75dc3dd46f8..23695d2476e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -295,6 +295,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) if (err) goto out; + tsk->flags &= ~PF_SU; + tsk->stack = ti; #ifdef CONFIG_SECCOMP /* diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ce9cd7bb9d0..037efc35a62 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -89,6 +89,38 @@ #define CREATE_TRACE_POINTS #include <trace/events/sched.h> +static atomic_t __su_instances; + +int su_instances(void) +{ + return atomic_read(&__su_instances); +} + +bool su_running(void) +{ + return su_instances() > 0; +} + +bool su_visible(void) +{ + uid_t uid = current_uid(); + if (su_running()) + return true; + if (uid == 0 || uid == 1000) + return true; + return false; +} + +void su_exec(void) +{ + atomic_inc(&__su_instances); +} + +void su_exit(void) +{ + atomic_dec(&__su_instances); +} + ATOMIC_NOTIFIER_HEAD(migration_notifier_head); void start_bandwidth_timer(struct hrtimer *period_timer, ktime_t period) |
