aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/events/core.c139
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/kprobes.c5
-rw-r--r--kernel/nsproxy.c3
4 files changed, 147 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 6f41548f2e32..16c877a121c8 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -48,6 +48,8 @@
48#include <linux/parser.h> 48#include <linux/parser.h>
49#include <linux/sched/clock.h> 49#include <linux/sched/clock.h>
50#include <linux/sched/mm.h> 50#include <linux/sched/mm.h>
51#include <linux/proc_ns.h>
52#include <linux/mount.h>
51 53
52#include "internal.h" 54#include "internal.h"
53 55
@@ -379,6 +381,7 @@ static DEFINE_PER_CPU(struct pmu_event_list, pmu_sb_events);
379 381
380static atomic_t nr_mmap_events __read_mostly; 382static atomic_t nr_mmap_events __read_mostly;
381static atomic_t nr_comm_events __read_mostly; 383static atomic_t nr_comm_events __read_mostly;
384static atomic_t nr_namespaces_events __read_mostly;
382static atomic_t nr_task_events __read_mostly; 385static atomic_t nr_task_events __read_mostly;
383static atomic_t nr_freq_events __read_mostly; 386static atomic_t nr_freq_events __read_mostly;
384static atomic_t nr_switch_events __read_mostly; 387static atomic_t nr_switch_events __read_mostly;
@@ -3991,6 +3994,8 @@ static void unaccount_event(struct perf_event *event)
3991 atomic_dec(&nr_mmap_events); 3994 atomic_dec(&nr_mmap_events);
3992 if (event->attr.comm) 3995 if (event->attr.comm)
3993 atomic_dec(&nr_comm_events); 3996 atomic_dec(&nr_comm_events);
3997 if (event->attr.namespaces)
3998 atomic_dec(&nr_namespaces_events);
3994 if (event->attr.task) 3999 if (event->attr.task)
3995 atomic_dec(&nr_task_events); 4000 atomic_dec(&nr_task_events);
3996 if (event->attr.freq) 4001 if (event->attr.freq)
@@ -6491,6 +6496,7 @@ static void perf_event_task(struct task_struct *task,
6491void perf_event_fork(struct task_struct *task) 6496void perf_event_fork(struct task_struct *task)
6492{ 6497{
6493 perf_event_task(task, NULL, 1); 6498 perf_event_task(task, NULL, 1);
6499 perf_event_namespaces(task);
6494} 6500}
6495 6501
6496/* 6502/*
@@ -6593,6 +6599,132 @@ void perf_event_comm(struct task_struct *task, bool exec)
6593} 6599}
6594 6600
6595/* 6601/*
6602 * namespaces tracking
6603 */
6604
6605struct perf_namespaces_event {
6606 struct task_struct *task;
6607
6608 struct {
6609 struct perf_event_header header;
6610
6611 u32 pid;
6612 u32 tid;
6613 u64 nr_namespaces;
6614 struct perf_ns_link_info link_info[NR_NAMESPACES];
6615 } event_id;
6616};
6617
6618static int perf_event_namespaces_match(struct perf_event *event)
6619{
6620 return event->attr.namespaces;
6621}
6622
6623static void perf_event_namespaces_output(struct perf_event *event,
6624 void *data)
6625{
6626 struct perf_namespaces_event *namespaces_event = data;
6627 struct perf_output_handle handle;
6628 struct perf_sample_data sample;
6629 int ret;
6630
6631 if (!perf_event_namespaces_match(event))
6632 return;
6633
6634 perf_event_header__init_id(&namespaces_event->event_id.header,
6635 &sample, event);
6636 ret = perf_output_begin(&handle, event,
6637 namespaces_event->event_id.header.size);
6638 if (ret)
6639 return;
6640
6641 namespaces_event->event_id.pid = perf_event_pid(event,
6642 namespaces_event->task);
6643 namespaces_event->event_id.tid = perf_event_tid(event,
6644 namespaces_event->task);
6645
6646 perf_output_put(&handle, namespaces_event->event_id);
6647
6648 perf_event__output_id_sample(event, &handle, &sample);
6649
6650 perf_output_end(&handle);
6651}
6652
6653static void perf_fill_ns_link_info(struct perf_ns_link_info *ns_link_info,
6654 struct task_struct *task,
6655 const struct proc_ns_operations *ns_ops)
6656{
6657 struct path ns_path;
6658 struct inode *ns_inode;
6659 void *error;
6660
6661 error = ns_get_path(&ns_path, task, ns_ops);
6662 if (!error) {
6663 ns_inode = ns_path.dentry->d_inode;
6664 ns_link_info->dev = new_encode_dev(ns_inode->i_sb->s_dev);
6665 ns_link_info->ino = ns_inode->i_ino;
6666 }
6667}
6668
6669void perf_event_namespaces(struct task_struct *task)
6670{
6671 struct perf_namespaces_event namespaces_event;
6672 struct perf_ns_link_info *ns_link_info;
6673
6674 if (!atomic_read(&nr_namespaces_events))
6675 return;
6676
6677 namespaces_event = (struct perf_namespaces_event){
6678 .task = task,
6679 .event_id = {
6680 .header = {
6681 .type = PERF_RECORD_NAMESPACES,
6682 .misc = 0,
6683 .size = sizeof(namespaces_event.event_id),
6684 },
6685 /* .pid */
6686 /* .tid */
6687 .nr_namespaces = NR_NAMESPACES,
6688 /* .link_info[NR_NAMESPACES] */
6689 },
6690 };
6691
6692 ns_link_info = namespaces_event.event_id.link_info;
6693
6694 perf_fill_ns_link_info(&ns_link_info[MNT_NS_INDEX],
6695 task, &mntns_operations);
6696
6697#ifdef CONFIG_USER_NS
6698 perf_fill_ns_link_info(&ns_link_info[USER_NS_INDEX],
6699 task, &userns_operations);
6700#endif
6701#ifdef CONFIG_NET_NS
6702 perf_fill_ns_link_info(&ns_link_info[NET_NS_INDEX],
6703 task, &netns_operations);
6704#endif
6705#ifdef CONFIG_UTS_NS
6706 perf_fill_ns_link_info(&ns_link_info[UTS_NS_INDEX],
6707 task, &utsns_operations);
6708#endif
6709#ifdef CONFIG_IPC_NS
6710 perf_fill_ns_link_info(&ns_link_info[IPC_NS_INDEX],
6711 task, &ipcns_operations);
6712#endif
6713#ifdef CONFIG_PID_NS
6714 perf_fill_ns_link_info(&ns_link_info[PID_NS_INDEX],
6715 task, &pidns_operations);
6716#endif
6717#ifdef CONFIG_CGROUPS
6718 perf_fill_ns_link_info(&ns_link_info[CGROUP_NS_INDEX],
6719 task, &cgroupns_operations);
6720#endif
6721
6722 perf_iterate_sb(perf_event_namespaces_output,
6723 &namespaces_event,
6724 NULL);
6725}
6726
6727/*
6596 * mmap tracking 6728 * mmap tracking
6597 */ 6729 */
6598 6730
@@ -9146,6 +9278,8 @@ static void account_event(struct perf_event *event)
9146 atomic_inc(&nr_mmap_events); 9278 atomic_inc(&nr_mmap_events);
9147 if (event->attr.comm) 9279 if (event->attr.comm)
9148 atomic_inc(&nr_comm_events); 9280 atomic_inc(&nr_comm_events);
9281 if (event->attr.namespaces)
9282 atomic_inc(&nr_namespaces_events);
9149 if (event->attr.task) 9283 if (event->attr.task)
9150 atomic_inc(&nr_task_events); 9284 atomic_inc(&nr_task_events);
9151 if (event->attr.freq) 9285 if (event->attr.freq)
@@ -9691,6 +9825,11 @@ SYSCALL_DEFINE5(perf_event_open,
9691 return -EACCES; 9825 return -EACCES;
9692 } 9826 }
9693 9827
9828 if (attr.namespaces) {
9829 if (!capable(CAP_SYS_ADMIN))
9830 return -EACCES;
9831 }
9832
9694 if (attr.freq) { 9833 if (attr.freq) {
9695 if (attr.sample_freq > sysctl_perf_event_sample_rate) 9834 if (attr.sample_freq > sysctl_perf_event_sample_rate)
9696 return -EINVAL; 9835 return -EINVAL;
diff --git a/kernel/fork.c b/kernel/fork.c
index 6c463c80e93d..afa2947286cd 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2352,6 +2352,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
2352 } 2352 }
2353 } 2353 }
2354 2354
2355 perf_event_namespaces(current);
2356
2355bad_unshare_cleanup_cred: 2357bad_unshare_cleanup_cred:
2356 if (new_cred) 2358 if (new_cred)
2357 put_cred(new_cred); 2359 put_cred(new_cred);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 448759d4a263..4780ec236035 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1740,11 +1740,12 @@ void unregister_kprobes(struct kprobe **kps, int num)
1740} 1740}
1741EXPORT_SYMBOL_GPL(unregister_kprobes); 1741EXPORT_SYMBOL_GPL(unregister_kprobes);
1742 1742
1743int __weak __kprobes kprobe_exceptions_notify(struct notifier_block *self, 1743int __weak kprobe_exceptions_notify(struct notifier_block *self,
1744 unsigned long val, void *data) 1744 unsigned long val, void *data)
1745{ 1745{
1746 return NOTIFY_DONE; 1746 return NOTIFY_DONE;
1747} 1747}
1748NOKPROBE_SYMBOL(kprobe_exceptions_notify);
1748 1749
1749static struct notifier_block kprobe_exceptions_nb = { 1750static struct notifier_block kprobe_exceptions_nb = {
1750 .notifier_call = kprobe_exceptions_notify, 1751 .notifier_call = kprobe_exceptions_notify,
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 782102e59eed..f6c5d330059a 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -26,6 +26,7 @@
26#include <linux/file.h> 26#include <linux/file.h>
27#include <linux/syscalls.h> 27#include <linux/syscalls.h>
28#include <linux/cgroup.h> 28#include <linux/cgroup.h>
29#include <linux/perf_event.h>
29 30
30static struct kmem_cache *nsproxy_cachep; 31static struct kmem_cache *nsproxy_cachep;
31 32
@@ -262,6 +263,8 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
262 goto out; 263 goto out;
263 } 264 }
264 switch_task_namespaces(tsk, new_nsproxy); 265 switch_task_namespaces(tsk, new_nsproxy);
266
267 perf_event_namespaces(tsk);
265out: 268out:
266 fput(file); 269 fput(file);
267 return err; 270 return err;