commit 4ed3fbc366d168806f94a615f3339b4d2fbd5a75 Author: David Smith Date: Wed Mar 22 15:51:56 2017 -0500 Fixed BZ1430828 by replacing task_exe_file() with current_exe_file(). * tapset/linux/task.stp (current_exe_file): New function. (task_exe_file): Deprecate and rewrite in terms of current_exe_file(). This keeps us from potentially accessing task->mm in an unsafe manner. * testsuite/buildok/task-embedded.stp: Updated. * testsuite/systemtap.base/task_paths.exp: Ditto. * testsuite/systemtap.base/task_paths.stp: Ditto. * doc/SystemTap_Tapset_Reference/man3/function::task_exe_file.3stap: Ditto. * doc/SystemTap_Tapset_Reference/man3/function::current_exe_file.3stap: New file. diff --git a/doc/SystemTap_Tapset_Reference/man3/function::current_exe_file.3stap b/doc/SystemTap_Tapset_Reference/man3/function::current_exe_file.3stap new file mode 100644 index 0000000..60ab1fa --- /dev/null +++ b/doc/SystemTap_Tapset_Reference/man3/function::current_exe_file.3stap @@ -0,0 +1,46 @@ +'\" t +.\" Title: function::current_exe_file +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.78.1 +.\" Date: March 2017 +.\" Manual: Context Functions +.\" Source: SystemTap Tapset Reference +.\" Language: English +.\" +.TH "FUNCTION::CURRENT_EX" "3stap" "March 2017" "SystemTap Tapset Reference" "Context Functions" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +function::current_exe_file \- get the file struct pointer for the current task\*(Aqs executable file +.SH "SYNOPSIS" +.sp +.nf + current_exe_file:long() +.fi +.SH "ARGUMENTS" +.PP +None +.SH "DESCRIPTION" +.PP +This function returns the file struct pointer for the +current task\*(Aqs executable file\&. Note that the file struct pointer +isn\*(Aqt locked on return\&. The return value of this function can be passed to +.IR function::fullpath_struct_file (3stap) +to get the path from the file struct\&. diff --git a/doc/SystemTap_Tapset_Reference/man3/function::task_exe_file.3stap b/doc/SystemTap_Tapset_Reference/man3/function::task_exe_file.3stap index bcc648b..55fe5d7 100644 --- a/doc/SystemTap_Tapset_Reference/man3/function::task_exe_file.3stap +++ b/doc/SystemTap_Tapset_Reference/man3/function::task_exe_file.3stap @@ -40,3 +40,8 @@ function::task_exe_file \- get the file struct pointer for a task\*(Aqs executab .RS 4 task_struct pointer\&. .RE +.SH "DESCRIPTION" +.PP +This function returns the file struct pointer for a task\*(Aqs executable file\&. Deprecated in SystemTap 3\&.2 and removed in SystemTap 3\&.3\&. +.SH SEE ALSO\n +.IR function::current_exe_file (3stap) diff --git a/tapset/linux/task.stp b/tapset/linux/task.stp index 12e2868..5467e05 100644 --- a/tapset/linux/task.stp +++ b/tapset/linux/task.stp @@ -781,39 +781,46 @@ function task_cwd_path:long(task:long) %} /** - * sfunction task_cwd_path - get the file struct pointer for a task's executable file + * sfunction current_exe_file - get the file struct pointer for the current task's executable file * - * @task: task_struct pointer. + * Description: This function returns the file struct pointer for the + * current task's executable file. Note that the file struct pointer + * isn't locked on return. The return value of this function can be + * passed to fullpath_struct_file() to get the path from the file + * struct. */ -function task_exe_file:long(task:long) +function current_exe_file:long() %{ /* pure */ - struct task_struct *task - = (struct task_struct *)(unsigned long)STAP_ARG_task; - struct mm_struct *mm = NULL; struct file *exe_file = NULL; - // Before using the task_struct pointer, make sure it is valid - // to read. - (void)kderef_buffer(NULL, task, sizeof(struct task_struct)); - - // OK, we now know it is valid to read. But, is it really a - // task struct? - if (!_stp_task_struct_valid(task)) { - STAP_ERROR ("invalid task struct pointer"); + if (current == NULL) { + STAP_ERROR ("No current task"); } - // We'd like to call get_task_mm()/mmput() here, but they can - // sleep. So, let's hope incrementing the task's usage (by - // calling get_task_struct) is enough to keep the mm around. - get_task_struct(task); - mm = task->mm; - if (mm) - exe_file = stap_find_exe_file(mm); - put_task_struct(task); - - if (exe_file) { - STAP_RETURN((unsigned long)exe_file); - fput(exe_file); + // Since we're stopped inside current, it isn't going away. So + // don't bother incrementing the task's usage count by calling + // get_task_struct()/put_task_struct(). We also don't need to + // bother to try to lock current->mm. + if (current->mm) { + exe_file = stap_find_exe_file(current->mm); + if (exe_file) { + STAP_RETVALUE = (unsigned long)exe_file; + fput(exe_file); + } } - CATCH_DEREF_FAULT(); %} + +%(systemtap_v <= "3.2" %? +/** + * sfunction task_exe_file - get the file struct pointer for a task's executable file + * + * @task: task_struct pointer. + */ +function task_exe_file:long(task:long) +{ + if (task == task_current()) { + return current_exe_file() + } + error("Only the exe file for the current task can be returned") +} +%) diff --git a/testsuite/buildok/task-embedded.stp b/testsuite/buildok/task-embedded.stp index 6b7983f..c3264b5 100755 --- a/testsuite/buildok/task-embedded.stp +++ b/testsuite/buildok/task-embedded.stp @@ -25,7 +25,10 @@ probe begin { pid2task(0) + task_fd_lookup(0, 0) + task_cwd_path(0) + - task_exe_file(0)) +%(systemtap_v <= "3.2" %? + task_exe_file(0) + +%) + current_exe_file()) print (task_execname (0)) print (pid2execname (0)) } diff --git a/testsuite/systemtap.base/task_paths.exp b/testsuite/systemtap.base/task_paths.exp index 0d885ee..a803680 100644 --- a/testsuite/systemtap.base/task_paths.exp +++ b/testsuite/systemtap.base/task_paths.exp @@ -36,7 +36,7 @@ if {$found_cwd == 0 && ![min_kernel_vers_p 2.6.25]} { setup_kfail NO_CWD *-*-* } -if {$found_cwd == 3 && $found_stapio == 2 && $found_error == 4 +if {$found_cwd == 2 && $found_stapio == 1 && $found_error == 2 && $found_whoami == 1} { pass "$test" } else { diff --git a/testsuite/systemtap.base/task_paths.stp b/testsuite/systemtap.base/task_paths.stp index be088a8..dfefa55 100644 --- a/testsuite/systemtap.base/task_paths.stp +++ b/testsuite/systemtap.base/task_paths.stp @@ -12,29 +12,8 @@ probe begin } try { - file = task_exe_file(task) - printf("current exe: %s\n", fullpath_struct_file(task, file)) - } - catch (msg) { - printf("ERROR: %s\n", msg) - } - - # Now print the value of cwd/exe for our target pid. Note that at - # this point, the target exe path will still be stapio - the exec - # hasn't happened yet. - try - { - task = pid2task(target()) - path = task_cwd_path(task) - printf("target cwd: %s\n", fullpath_struct_path(path)) - } - catch (msg) { - printf("ERROR: %s\n", msg) - } - try - { - file = task_exe_file(task) - printf("target exe: %s\n", fullpath_struct_file(task, file)) + file = current_exe_file() + printf("current exe: %s\n", fullpath_struct_file(task_current(), file)) } catch (msg) { printf("ERROR: %s\n", msg) @@ -51,15 +30,6 @@ probe begin catch (msg) { printf("ERROR: %s\n", msg) } - try - { - file = task_exe_file(task) - printf("file: %p\n", file) - printf("%s\n", fullpath_struct_file(task, file)) - } - catch (msg) { - printf("ERROR: %s\n", msg) - } # Now let's try using a task pointer of -1, which should also # fail. @@ -72,14 +42,6 @@ probe begin catch (msg) { printf("ERROR: %s\n", msg) } - try - { - file = task_exe_file(task) - printf("%s\n", fullpath_struct_file(task, file)) - } - catch (msg) { - printf("ERROR: %s\n", msg) - } } probe syscall.geteuid, syscall.getuid @@ -99,8 +61,8 @@ probe syscall.geteuid, syscall.getuid } try { - file = task_exe_file(task) - printf("current exe: %s\n", fullpath_struct_file(task, file)) + file = current_exe_file() + printf("current exe: %s\n", fullpath_struct_file(task_current(), file)) } catch (msg) { printf("ERROR: %s\n", msg)