tracing: Updates for 5.16-rc5
Subsystems (4)
Steven Rostedt
maintainercover 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
Steven Rostedt
maintainerPATCH 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.
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
@@ -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
Steven Rostedt
maintainerPATCH 2/5 tracefs: Set all files to the same group ownership as the mount option
In reply to Steven RostedtFrom: "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.
--- fs/tracefs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
fs/tracefs/inode.c +72 -0
@@ -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
Steven Rostedt
maintainerPATCH 3/5 ftrace: Use direct_ops hash in unregister_ftrace_direct
In reply to Steven RostedtFrom: 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.
--- kernel/trace/ftrace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/trace/ftrace.c +3 -1
@@ -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
Steven Rostedt
maintainerPATCH 4/5 ftrace: Add cleanup to unregister_ftrace_direct_multi
In reply to Steven RostedtFrom: Jiri Olsa <[email protected]>
Adding ops cleanup to unregister_ftrace_direct_multi, so it can be reused in another register call.
--- kernel/trace/ftrace.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/trace/ftrace.c +4 -0
@@ -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
Steven Rostedt
maintainerPATCH 5/5 ftrace/samples: Add module to test multi direct modify interface
In reply to Steven RostedtFrom: 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
@@ -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
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_multiAPI. 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_multito change the trampoline address for the directftrace_ops. The ftracetrace_pipethen shows trace from both trampolines.Cc Ingo Molnar <[email protected]>Cc Heiko Carstens <[email protected]>Signed-off-by Jiri Olsa <[email protected]>Signed-off-by Steven Rostedt (VMware) <[email protected]>
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:
Steven Rostedt
maintainerRe: [for-linus][PATCH 5/5] ftrace/samples: Add module to test multi direct modify interface
Quoted 4 lines · On Thu, 9 Dec 2021 18:50:57 +0100 Heiko Carstens <[email protected]> wrote:
FWIW, for the s390 bits in here:
Reviewed-by Heiko Carstens <[email protected]>Tested-by Heiko Carstens <[email protected]>
Thanks! I'll update the tags. (one of the reasons I post patches before sending a pull request).
-- Steve