Blob Blame History Raw
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)