commit 4ed3fbc366d168806f94a615f3339b4d2fbd5a75
Author: David Smith <dsmith@redhat.com>
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 <http://docbook.sf.net/>
+.\" 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)