diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/core.c | 14 | ||||
| -rw-r--r-- | kernel/trace/trace_event_perf.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_uprobe.c | 2 |
3 files changed, 20 insertions, 0 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index fc1c330c6bd6..2d5fe26551f8 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -4447,6 +4447,9 @@ static void _free_event(struct perf_event *event) | |||
| 4447 | if (event->ctx) | 4447 | if (event->ctx) |
| 4448 | put_ctx(event->ctx); | 4448 | put_ctx(event->ctx); |
| 4449 | 4449 | ||
| 4450 | if (event->hw.target) | ||
| 4451 | put_task_struct(event->hw.target); | ||
| 4452 | |||
| 4450 | exclusive_event_destroy(event); | 4453 | exclusive_event_destroy(event); |
| 4451 | module_put(event->pmu->module); | 4454 | module_put(event->pmu->module); |
| 4452 | 4455 | ||
| @@ -8397,6 +8400,10 @@ static int perf_kprobe_event_init(struct perf_event *event) | |||
| 8397 | 8400 | ||
| 8398 | if (event->attr.type != perf_kprobe.type) | 8401 | if (event->attr.type != perf_kprobe.type) |
| 8399 | return -ENOENT; | 8402 | return -ENOENT; |
| 8403 | |||
| 8404 | if (!capable(CAP_SYS_ADMIN)) | ||
| 8405 | return -EACCES; | ||
| 8406 | |||
| 8400 | /* | 8407 | /* |
| 8401 | * no branch sampling for probe events | 8408 | * no branch sampling for probe events |
| 8402 | */ | 8409 | */ |
| @@ -8434,6 +8441,10 @@ static int perf_uprobe_event_init(struct perf_event *event) | |||
| 8434 | 8441 | ||
| 8435 | if (event->attr.type != perf_uprobe.type) | 8442 | if (event->attr.type != perf_uprobe.type) |
| 8436 | return -ENOENT; | 8443 | return -ENOENT; |
| 8444 | |||
| 8445 | if (!capable(CAP_SYS_ADMIN)) | ||
| 8446 | return -EACCES; | ||
| 8447 | |||
| 8437 | /* | 8448 | /* |
| 8438 | * no branch sampling for probe events | 8449 | * no branch sampling for probe events |
| 8439 | */ | 8450 | */ |
| @@ -9955,6 +9966,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
| 9955 | * and we cannot use the ctx information because we need the | 9966 | * and we cannot use the ctx information because we need the |
| 9956 | * pmu before we get a ctx. | 9967 | * pmu before we get a ctx. |
| 9957 | */ | 9968 | */ |
| 9969 | get_task_struct(task); | ||
| 9958 | event->hw.target = task; | 9970 | event->hw.target = task; |
| 9959 | } | 9971 | } |
| 9960 | 9972 | ||
| @@ -10070,6 +10082,8 @@ err_ns: | |||
| 10070 | perf_detach_cgroup(event); | 10082 | perf_detach_cgroup(event); |
| 10071 | if (event->ns) | 10083 | if (event->ns) |
| 10072 | put_pid_ns(event->ns); | 10084 | put_pid_ns(event->ns); |
| 10085 | if (event->hw.target) | ||
| 10086 | put_task_struct(event->hw.target); | ||
| 10073 | kfree(event); | 10087 | kfree(event); |
| 10074 | 10088 | ||
| 10075 | return ERR_PTR(err); | 10089 | return ERR_PTR(err); |
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 2c416509b834..c79193e598f5 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
| @@ -252,6 +252,8 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) | |||
| 252 | ret = strncpy_from_user( | 252 | ret = strncpy_from_user( |
| 253 | func, u64_to_user_ptr(p_event->attr.kprobe_func), | 253 | func, u64_to_user_ptr(p_event->attr.kprobe_func), |
| 254 | KSYM_NAME_LEN); | 254 | KSYM_NAME_LEN); |
| 255 | if (ret == KSYM_NAME_LEN) | ||
| 256 | ret = -E2BIG; | ||
| 255 | if (ret < 0) | 257 | if (ret < 0) |
| 256 | goto out; | 258 | goto out; |
| 257 | 259 | ||
| @@ -300,6 +302,8 @@ int perf_uprobe_init(struct perf_event *p_event, bool is_retprobe) | |||
| 300 | return -ENOMEM; | 302 | return -ENOMEM; |
| 301 | ret = strncpy_from_user( | 303 | ret = strncpy_from_user( |
| 302 | path, u64_to_user_ptr(p_event->attr.uprobe_path), PATH_MAX); | 304 | path, u64_to_user_ptr(p_event->attr.uprobe_path), PATH_MAX); |
| 305 | if (ret == PATH_MAX) | ||
| 306 | return -E2BIG; | ||
| 303 | if (ret < 0) | 307 | if (ret < 0) |
| 304 | goto out; | 308 | goto out; |
| 305 | if (path[0] == '\0') { | 309 | if (path[0] == '\0') { |
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 469ba7ecd14b..34fd0e0ec51d 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
| @@ -151,6 +151,8 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, | |||
| 151 | return; | 151 | return; |
| 152 | 152 | ||
| 153 | ret = strncpy_from_user(dst, src, maxlen); | 153 | ret = strncpy_from_user(dst, src, maxlen); |
| 154 | if (ret == maxlen) | ||
| 155 | dst[--ret] = '\0'; | ||
| 154 | 156 | ||
| 155 | if (ret < 0) { /* Failed to fetch string */ | 157 | if (ret < 0) { /* Failed to fetch string */ |
| 156 | ((u8 *)get_rloc_data(dest))[0] = '\0'; | 158 | ((u8 *)get_rloc_data(dest))[0] = '\0'; |
