From: Steven Rostedt <rostedt@goodmis.org>
Some of the system calls that read a fixed length of memory from the user
space address are not arrays but strings. Take a bit away from the nb_args
field in the syscall meta data to use as a flag to denote that the system
call's user_arg_size is being used as a string. The nb_args should never
be more than 6, so 7 bits is plenty to hold that number. When the
user_arg_is_str flag that, when set, will display the data array from the
user space address as a string and not an array.
This will allow the output to look like this:
sys_sethostname(name: 0x5584310eb2a0 "debian", len: 6)
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
include/trace/syscall.h | 4 +++-
kernel/trace/trace_syscalls.c | 25 +++++++++++++++++++------
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 9413c139da66..0dd7f2b33431 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -16,6 +16,7 @@
* @name: name of the syscall
* @syscall_nr: number of the syscall
* @nb_args: number of parameters it takes
+ * @user_arg_is_str: set if the arg for @user_arg_size is a string
* @user_arg_size: holds @arg that has size of the user space to read
* @user_mask: mask of @args that will read user space
* @types: list of types as strings
@@ -27,7 +28,8 @@
struct syscall_metadata {
const char *name;
int syscall_nr;
- u8 nb_args;
+ u8 nb_args:7;
+ u8 user_arg_is_str:1;
s8 user_arg_size;
short user_mask;
const char **types;
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index b0a587f2e4b5..8c0142eea898 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -182,14 +182,13 @@ print_syscall_enter(struct trace_iterator *iter, int flags,
val = *(int *)ptr;
ptr = (void *)ent + (val & 0xffff);
+ len = val >> 16;
- if (entry->user_arg_size < 0) {
- trace_seq_printf(s, " \"%s\"", ptr);
+ if (entry->user_arg_size < 0 || entry->user_arg_is_str) {
+ trace_seq_printf(s, " \"%.*s\"", len, ptr);
continue;
}
- len = val >> 16;
-
val = trace->args[entry->user_arg_size];
trace_seq_puts(s, " (");
@@ -250,6 +249,7 @@ print_syscall_exit(struct trace_iterator *iter, int flags,
static int __init
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
{
+ bool is_string = entry->user_arg_is_str;
int i;
int pos = 0;
@@ -267,7 +267,7 @@ __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
continue;
/* Add the format for the user space string or array */
- if (entry->user_arg_size < 0)
+ if (entry->user_arg_size < 0 || is_string)
pos += snprintf(buf + pos, LEN_OR_ZERO, " \\\"%%s\\\"");
else
pos += snprintf(buf + pos, LEN_OR_ZERO, " (%%s)");
@@ -280,7 +280,7 @@ __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
if (!(BIT(i) & entry->user_mask))
continue;
/* The user space data for arg has name __<arg>_val */
- if (entry->user_arg_size < 0) {
+ if (entry->user_arg_size < 0 || is_string) {
pos += snprintf(buf + pos, LEN_OR_ZERO, ", __get_str(__%s_val)",
entry->args[i]);
} else {
@@ -872,6 +872,19 @@ static void check_faultable_syscall(struct trace_event_call *call, int nr)
sys_data->user_mask = BIT(1);
sys_data->user_arg_size = 2;
break;
+ /* user arg 0 with size arg at 1 as string */
+ case __NR_setdomainname:
+ case __NR_sethostname:
+ sys_data->user_mask = BIT(0);
+ sys_data->user_arg_size = 1;
+ sys_data->user_arg_is_str = 1;
+ break;
+ /* user arg 4 with size arg at 3 as string */
+ case __NR_kexec_file_load:
+ sys_data->user_mask = BIT(4);
+ sys_data->user_arg_size = 3;
+ sys_data->user_arg_is_str = 1;
+ break;
/* user arg at position 0 */
case __NR_access:
case __NR_acct:
--
2.47.2
Hi Steven, kernel test robot noticed the following build errors: [auto build test ERROR on trace/for-next] [also build test ERROR on linus/master v6.16 next-20250806] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Steven-Rostedt/tracing-Replace-syscall-RCU-pointer-assignment-with-READ-WRITE_ONCE/20250806-122312 base: https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next patch link: https://lore.kernel.org/r/20250805193235.416382557%40kernel.org patch subject: [PATCH 5/7] tracing: Display some syscall arrays as strings config: i386-randconfig-141-20250806 (https://download.01.org/0day-ci/archive/20250806/202508062215.aRvDXrBA-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250806/202508062215.aRvDXrBA-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202508062215.aRvDXrBA-lkp@intel.com/ All errors (new ones prefixed by >>): kernel/trace/trace_syscalls.c: In function 'check_faultable_syscall': >> kernel/trace/trace_syscalls.c:883:14: error: '__NR_kexec_file_load' undeclared (first use in this function) 883 | case __NR_kexec_file_load: | ^~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_syscalls.c:883:14: note: each undeclared identifier is reported only once for each function it appears in kernel/trace/trace_syscalls.c:957:14: error: '__NR_newfstatat' undeclared (first use in this function) 957 | case __NR_newfstatat: | ^~~~~~~~~~~~~~~ vim +/__NR_kexec_file_load +883 kernel/trace/trace_syscalls.c 851 852 /* 853 * For system calls that reference user space memory that can 854 * be recorded into the event, set the system call meta data's user_mask 855 * to the "args" index that points to the user space memory to retrieve. 856 */ 857 static void check_faultable_syscall(struct trace_event_call *call, int nr) 858 { 859 struct syscall_metadata *sys_data = call->data; 860 861 /* Only work on entry */ 862 if (sys_data->enter_event != call) 863 return; 864 865 sys_data->user_arg_size = -1; 866 867 switch (nr) { 868 /* user arg 1 with size arg at 2 */ 869 case __NR_write: 870 case __NR_mq_timedsend: 871 case __NR_pwrite64: 872 sys_data->user_mask = BIT(1); 873 sys_data->user_arg_size = 2; 874 break; 875 /* user arg 0 with size arg at 1 as string */ 876 case __NR_setdomainname: 877 case __NR_sethostname: 878 sys_data->user_mask = BIT(0); 879 sys_data->user_arg_size = 1; 880 sys_data->user_arg_is_str = 1; 881 break; 882 /* user arg 4 with size arg at 3 as string */ > 883 case __NR_kexec_file_load: 884 sys_data->user_mask = BIT(4); 885 sys_data->user_arg_size = 3; 886 sys_data->user_arg_is_str = 1; 887 break; 888 /* user arg at position 0 */ 889 case __NR_access: 890 case __NR_acct: 891 case __NR_add_key: /* Just _type. TODO add _description */ 892 case __NR_chdir: 893 case __NR_chown: 894 case __NR_chmod: 895 case __NR_chroot: 896 case __NR_creat: 897 case __NR_delete_module: 898 case __NR_execve: 899 case __NR_fsopen: 900 case __NR_getxattr: /* Just pathname, TODO add name */ 901 case __NR_lchown: 902 case __NR_lgetxattr: /* Just pathname, TODO add name */ 903 case __NR_lremovexattr: /* Just pathname, TODO add name */ 904 case __NR_link: /* Just oldname. TODO add newname */ 905 case __NR_listxattr: /* Just pathname, TODO add list */ 906 case __NR_llistxattr: /* Just pathname, TODO add list */ 907 case __NR_lsetxattr: /* Just pathname, TODO add list */ 908 case __NR_open: 909 case __NR_memfd_create: 910 case __NR_mount: /* Just dev_name, TODO add dir_name and type */ 911 case __NR_mkdir: 912 case __NR_mknod: 913 case __NR_mq_open: 914 case __NR_mq_unlink: 915 case __NR_pivot_root: /* Just new_root, TODO add old_root */ 916 case __NR_readlink: 917 case __NR_removexattr: /* Just pathname, TODO add name */ 918 case __NR_rename: /* Just oldname. TODO add newname */ 919 case __NR_request_key: /* Just _type. TODO add _description */ 920 case __NR_rmdir: 921 case __NR_setxattr: /* Just pathname, TODO add list */ 922 case __NR_shmdt: 923 case __NR_statfs: 924 case __NR_swapon: 925 case __NR_swapoff: 926 case __NR_symlink: /* Just oldname. TODO add newname */ 927 case __NR_truncate: 928 case __NR_unlink: 929 case __NR_umount2: 930 case __NR_utime: 931 case __NR_utimes: 932 sys_data->user_mask = BIT(0); 933 break; 934 /* user arg at position 1 */ 935 case __NR_execveat: 936 case __NR_faccessat: 937 case __NR_faccessat2: 938 case __NR_finit_module: 939 case __NR_fchmodat: 940 case __NR_fchmodat2: 941 case __NR_fchownat: 942 case __NR_fgetxattr: 943 case __NR_flistxattr: 944 case __NR_fsetxattr: 945 case __NR_fspick: 946 case __NR_fremovexattr: 947 case __NR_futimesat: 948 case __NR_getxattrat: /* Just pathname, TODO add name */ 949 case __NR_inotify_add_watch: 950 case __NR_linkat: /* Just oldname. TODO add newname */ 951 case __NR_listxattrat: /* Just pathname, TODO add list */ 952 case __NR_mkdirat: 953 case __NR_mknodat: 954 case __NR_mount_setattr: 955 case __NR_move_mount: /* Just from_pathname, TODO add to_pathname */ 956 case __NR_name_to_handle_at: 957 case __NR_newfstatat: 958 case __NR_openat: 959 case __NR_openat2: 960 case __NR_open_tree: 961 case __NR_open_tree_attr: 962 case __NR_readlinkat: 963 case __NR_renameat: /* Just oldname. TODO add newname */ 964 case __NR_renameat2: /* Just oldname. TODO add newname */ 965 case __NR_removexattrat: /* Just pathname, TODO add name */ 966 case __NR_quotactl: 967 case __NR_setxattrat: /* Just pathname, TODO add list */ 968 case __NR_syslog: 969 case __NR_symlinkat: /* Just oldname. TODO add newname */ 970 case __NR_statx: 971 case __NR_unlinkat: 972 case __NR_utimensat: 973 sys_data->user_mask = BIT(1); 974 break; 975 /* user arg at position 2 */ 976 case __NR_init_module: 977 case __NR_fsconfig: 978 sys_data->user_mask = BIT(2); 979 break; 980 /* user arg at position 4 */ 981 case __NR_fanotify_mark: 982 sys_data->user_mask = BIT(4); 983 break; 984 default: 985 sys_data->user_mask = 0; 986 } 987 } 988 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.