Skip to contentSkip to conversation

tracing: Updates for 5.16-rc5

PATCH In review Steven Rostedt 2 participants 8 messages Dec 9, 2021

Subsystems (4)
lore
Share & tools
lore

Steven Rostedt

author maintainer
#0 lore raw

cover tracing: Updates for 5.16-rc5

Ftrace and tracefs fixes:

- Have tracefs honor the gid mount option

- Have new files in tracefs inherit the parent ownership

- Have direct_ops unregister when it has no more functions

- Properly clean up the ops when unregistering multi direct ops

- Add a sample module to test the multiple direct ops

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
ftrace/urgent

Head SHA1: 72a86f97053fc70c8cfa6bdef3154bda8a811041

Jiri Olsa (3):
ftrace: Use direct_ops hash in unregister_ftrace_direct
ftrace: Add cleanup to unregister_ftrace_direct_multi ftrace/samples: Add module to test multi direct modify interface

Steven Rostedt (VMware) (2):
tracefs: Have new files inherit the ownership of their parent
tracefs: Set all files to the same group ownership as the mount option

----

 fs/tracefs/inode.c                          |  76 ++++++++++++++
 kernel/trace/ftrace.c                       |   8 +-
 samples/ftrace/Makefile                     |   1 +
 samples/ftrace/ftrace-direct-multi-modify.c | 152 ++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+), 1 deletion(-)
 create mode 100644 samples/ftrace/ftrace-direct-multi-modify.c
author maintainer
#1 lore raw

PATCH 1/5 tracefs: Have new files inherit the ownership of their parent

From: "Steven Rostedt (VMware)" <[email protected]>

If directories in tracefs have their ownership changed, then any new files and directories that are created under those directories should inherit the ownership of the director they are created in.

Cc Kees Cook <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Al Viro <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc Yabin Cui <[email protected]>
Cc Christian Brauner <[email protected]>
Fixes 4282d60689d4f ("tracefs: Add new tracefs file system")

Reported: https://lore.kernel.org/all/CAC_TJve8MMAv+H_NdLSJXZUSoxOEq2zB_pVaJ9p=7H6Bu3X76g@mail.gmail.com/

---
 fs/tracefs/inode.c | 4 ++++
 1 file changed, 4 insertions(+)
fs/tracefs/inode.c +4 -0
index 925a621b432e..06cf0534cc60 100644
@@ -414,6 +414,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
 	inode->i_mode = mode;
 	inode->i_fop = fops ? fops : &tracefs_file_operations;
 	inode->i_private = data;
+	inode->i_uid = d_inode(dentry->d_parent)->i_uid;
+	inode->i_gid = d_inode(dentry->d_parent)->i_gid;
 	d_instantiate(dentry, inode);
 	fsnotify_create(dentry->d_parent->d_inode, dentry);
 	return end_creating(dentry);
@@ -436,6 +438,8 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent,
 	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP;
 	inode->i_op = ops;
 	inode->i_fop = &simple_dir_operations;
+	inode->i_uid = d_inode(dentry->d_parent)->i_uid;
+	inode->i_gid = d_inode(dentry->d_parent)->i_gid;
 
 	/* directory inodes start off with i_nlink == 2 (for "." entry) */
 	inc_nlink(inode);
Signature · 1 line
2.33.0
author maintainer
#2 lore raw

PATCH 2/5 tracefs: Set all files to the same group ownership as the mount option

In reply to Steven Rostedt

From: "Steven Rostedt (VMware)" <[email protected]>

As people have been asking to allow non-root processes to have access to the tracefs directory, it was considered best to only allow groups to have access to the directory, where it is easier to just set the tracefs file system to a specific group (as other would be too dangerous), and that way the admins could pick which processes would have access to tracefs.

Unfortunately, this broke tooling on Android that expected the other bit to be set. For some special cases, for non-root tools to trace the system, tracefs would be mounted and change the permissions of the top level directory which gave access to all running tasks permission to the tracing directory. Even though this would be dangerous to do in a production environment, for testing environments this can be useful.

Now with the new changes to not allow other (which is still the proper thing to do), it breaks the testing tooling. Now more code needs to be loaded on the system to change ownership of the tracing directory.

The real solution is to have tracefs honor the gid=xxx option when mounting. That is,

(tracing group tracing has value 1003)

mount -t tracefs -o gid=1003 tracefs /sys/kernel/tracing

should have it that all files in the tracing directory should be of the given group.

Copy the logic from d_walk() from dcache.c and simplify it for the mount case of tracefs if gid is set. All the files in tracefs will be walked and their group will be set to the value passed in.

Cc Ingo Molnar <[email protected]>
Cc Kees Cook <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Al Viro <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Fixes 49d67e445742 ("tracefs: Have tracefs directories not set OTH permission bits by default")
---
 fs/tracefs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
fs/tracefs/inode.c +72 -0
index 06cf0534cc60..3616839c5c4b 100644
@@ -161,6 +161,77 @@ struct tracefs_fs_info {
 	struct tracefs_mount_opts mount_opts;
 };
 
+static void change_gid(struct dentry *dentry, kgid_t gid)
+{
+	if (!dentry->d_inode)
+		return;
+	dentry->d_inode->i_gid = gid;
+}
+
+/*
+ * Taken from d_walk, but without he need for handling renames.
+ * Nothing can be renamed while walking the list, as tracefs
+ * does not support renames. This is only called when mounting
+ * or remounting the file system, to set all the files to
+ * the given gid.
+ */
+static void set_gid(struct dentry *parent, kgid_t gid)
+{
+	struct dentry *this_parent;
+	struct list_head *next;
+
+	this_parent = parent;
+	spin_lock(&this_parent->d_lock);
+
+	change_gid(this_parent, gid);
+repeat:
+	next = this_parent->d_subdirs.next;
+resume:
+	while (next != &this_parent->d_subdirs) {
+		struct list_head *tmp = next;
+		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+		next = tmp->next;
+
+		spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+
+		change_gid(dentry, gid);
+
+		if (!list_empty(&dentry->d_subdirs)) {
+			spin_unlock(&this_parent->d_lock);
+			spin_release(&dentry->d_lock.dep_map, _RET_IP_);
+			this_parent = dentry;
+			spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
+			goto repeat;
+		}
+		spin_unlock(&dentry->d_lock);
+	}
+	/*
+	 * All done at this level ... ascend and resume the search.
+	 */
+	rcu_read_lock();
+ascend:
+	if (this_parent != parent) {
+		struct dentry *child = this_parent;
+		this_parent = child->d_parent;
+
+		spin_unlock(&child->d_lock);
+		spin_lock(&this_parent->d_lock);
+
+		/* go into the first sibling still alive */
+		do {
+			next = child->d_child.next;
+			if (next == &this_parent->d_subdirs)
+				goto ascend;
+			child = list_entry(next, struct dentry, d_child);
+		} while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED));
+		rcu_read_unlock();
+		goto resume;
+	}
+	rcu_read_unlock();
+	spin_unlock(&this_parent->d_lock);
+	return;
+}
+
 static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
 {
 	substring_t args[MAX_OPT_ARGS];
@@ -193,6 +264,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
 			if (!gid_valid(gid))
 				return -EINVAL;
 			opts->gid = gid;
+			set_gid(tracefs_mount->mnt_root, gid);
 			break;
 		case Opt_mode:
 			if (match_octal(&args[0], &option))
Signature · 1 line
2.33.0
author maintainer
#3 lore raw

PATCH 3/5 ftrace: Use direct_ops hash in unregister_ftrace_direct

In reply to Steven Rostedt

From: Jiri Olsa <[email protected]>

Now when we have *direct_multi interface the direct_functions hash is no longer owned just by direct_ops. It's also used by any other ftrace_ops passed to *direct_multi interface.

Thus to find out that we are unregistering the last function from direct_ops, we need to check directly direct_ops's hash.

Cc Ingo Molnar <[email protected]>
Cc Heiko Carstens <[email protected]>
Fixes f64dd4627ec6 ("ftrace: Add multi direct register/unregister interface")
---
 kernel/trace/ftrace.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/trace/ftrace.c +3 -1
index 30bc880c3849..7f0594e28226 100644
@@ -5217,6 +5217,7 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
 {
 	struct ftrace_direct_func *direct;
 	struct ftrace_func_entry *entry;
+	struct ftrace_hash *hash;
 	int ret = -ENODEV;
 
 	mutex_lock(&direct_mutex);
@@ -5225,7 +5226,8 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
 	if (!entry)
 		goto out_unlock;
 
-	if (direct_functions->count == 1)
+	hash = direct_ops.func_hash->filter_hash;
+	if (hash->count == 1)
 		unregister_ftrace_function(&direct_ops);
 
 	ret = ftrace_set_filter_ip(&direct_ops, ip, 1, 0);
Signature · 1 line
2.33.0
author maintainer
#4 lore raw

PATCH 4/5 ftrace: Add cleanup to unregister_ftrace_direct_multi

In reply to Steven Rostedt

From: Jiri Olsa <[email protected]>

Adding ops cleanup to unregister_ftrace_direct_multi, so it can be reused in another register call.

Cc Ingo Molnar <[email protected]>
Cc Heiko Carstens <[email protected]>
Fixes f64dd4627ec6 ("ftrace: Add multi direct register/unregister interface")
---
 kernel/trace/ftrace.c | 4 ++++
 1 file changed, 4 insertions(+)
kernel/trace/ftrace.c +4 -0
index 7f0594e28226..be5f6b32a012 100644
@@ -5542,6 +5542,10 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
 	err = unregister_ftrace_function(ops);
 	remove_direct_functions_hash(hash, addr);
 	mutex_unlock(&direct_mutex);
+
+	/* cleanup for possible another register call */
+	ops->func = NULL;
+	ops->trampoline = 0;
 	return err;
 }
 EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
Signature · 1 line
2.33.0
author maintainer
#5 lore raw

PATCH 5/5 ftrace/samples: Add module to test multi direct modify interface

In reply to Steven Rostedt

From: Jiri Olsa <[email protected]>

Adding ftrace-direct-multi-modify.ko kernel module that uses modify_ftrace_direct_multi API. The core functionality is taken from ftrace-direct-modify.ko kernel module and changed to fit multi direct interface.

The init function creates kthread that periodically calls modify_ftrace_direct_multi to change the trampoline address for the direct ftrace_ops. The ftrace trace_pipe then shows trace from both trampolines.

---
 samples/ftrace/Makefile                     |   1 +
 samples/ftrace/ftrace-direct-multi-modify.c | 152 ++++++++++++++++++++
 2 files changed, 153 insertions(+)
 create mode 100644 samples/ftrace/ftrace-direct-multi-modify.c
samples/ftrace/Makefile +1 -0
index b9198e2eef28..faf8cdb79c5f 100644
@@ -4,6 +4,7 @@ obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct.o
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-too.o
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT) += ftrace-direct-modify.o
 obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi.o
+obj-$(CONFIG_SAMPLE_FTRACE_DIRECT_MULTI) += ftrace-direct-multi-modify.o
 
 CFLAGS_sample-trace-array.o := -I$(src)
 obj-$(CONFIG_SAMPLE_TRACE_ARRAY) += sample-trace-array.o
samples/ftrace/ftrace-direct-multi-modify.c new file +152 -0

152 lines not on this page · raw message

Signature · 1 line
2.33.0
Reviewed-by Tested-by on v1 5/5
#6 lore raw

Re: [for-linus][PATCH 5/5] ftrace/samples: Add module to test multi direct modify interface

Quoted 18 lines · Steven Rostedt

From: Jiri Olsa <[email protected]>

Adding ftrace-direct-multi-modify.ko kernel module that uses modify_ftrace_direct_multi API. The core functionality is taken from ftrace-direct-modify.ko kernel module and changed to fit multi direct interface.

The init function creates kthread that periodically calls modify_ftrace_direct_multi to change the trampoline address for the direct ftrace_ops. The ftrace trace_pipe then shows trace from both trampolines.

Quoted 5 lines
---
 samples/ftrace/Makefile                     |   1 +
 samples/ftrace/ftrace-direct-multi-modify.c | 152 ++++++++++++++++++++
 2 files changed, 153 insertions(+)
 create mode 100644 samples/ftrace/ftrace-direct-multi-modify.c

FWIW, for the s390 bits in here: