Blame SOURCES/0180-pathtrace-util-do-not-print-deleted-as-part-of-the-p.patch

51d9a3
From 676979fa9cc7920e5e4d547814f9c0edb597fa0d Mon Sep 17 00:00:00 2001
51d9a3
From: Eugene Syromyatnikov <evgsyr@gmail.com>
51d9a3
Date: Thu, 30 Jun 2022 16:01:05 +0200
51d9a3
Subject: [PATCH] pathtrace, util: do not print " (deleted)" as part of the
51d9a3
 path
51d9a3
51d9a3
In order to allow to discern the unlinked paths from the paths that
51d9a3
do indeed end with " (deleted)".
51d9a3
51d9a3
* src/defs.h (getfdpath_pid): Add deleted parameter.
51d9a3
(getfdpath): Pass NULL as deleted parameter to getfdpath_pid.
51d9a3
* src/largefile_wrappers.h (lstat_file): New macro.
51d9a3
* src/pathtrace.c: Include <sys/stat.h>, <sys/types.h>, <unistd.h>,
51d9a3
and "largefile_wrappers.h".
51d9a3
(getfdpath_pid): Add deleted parameter, check if path ends with
51d9a3
" (deleted)", and if it is, try to figure out if it is a part
51d9a3
of the path by comparing device/inode numbers of the file procfs
51d9a3
link resolves into and the file pointed by the path read;  strip
51d9a3
" (deleted)";  set deleted (if it is non-NULL) to true if the fd
51d9a3
is turned out to be deleted and to false otherwise.
51d9a3
* src/util.c (print_quoted_string_in_angle_brackets): Add deleted
51d9a3
parameter, print "(deleted)" after the closing angle bracket if it is
51d9a3
non-NULL.
51d9a3
(printfd_pid): Add deleted local variable, pass it to getfdpath_pid
51d9a3
and print_quoted_string_in_angle_brackets calls.
51d9a3
* tests/fchmod.c: Add checks for a file with " (deleted)" in the path,
51d9a3
update expected output.
51d9a3
* NEWS: Mention the change.
51d9a3
---
51d9a3
 NEWS                     |  5 +++++
51d9a3
 src/defs.h               |  5 +++--
51d9a3
 src/largefile_wrappers.h |  2 ++
51d9a3
 src/pathtrace.c          | 48 +++++++++++++++++++++++++++++++++++++++++++++---
51d9a3
 src/util.c               | 10 +++++++---
51d9a3
 tests/fchmod.c           | 47 +++++++++++++++++++++++++++++++++++++++++++----
51d9a3
 6 files changed, 105 insertions(+), 12 deletions(-)
51d9a3
51d9a3
Index: strace-5.18/NEWS
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/NEWS	2022-07-13 12:52:48.219784860 +0200
51d9a3
+++ strace-5.18/NEWS	2022-07-13 12:52:48.451782122 +0200
51d9a3
@@ -1,6 +1,11 @@
51d9a3
 Noteworthy changes in release 5.18 (2022-06-18)
51d9a3
 ===============================================
51d9a3
 
51d9a3
+* Changes in behaviour
51d9a3
+  * The "(deleted)" marker for unlinked paths of file descriptors is now printed
51d9a3
+    outside angle brackets;  the matching of unlinked paths of file descriptors
51d9a3
+    no longer includes the " (deleted)" part into consideration.
51d9a3
+
51d9a3
 * Improvements
51d9a3
   * Added an interface of raising des Strausses awareness.
51d9a3
   * Added --tips option to print strace tips, tricks, and tweaks
51d9a3
Index: strace-5.18/src/defs.h
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/src/defs.h	2022-07-13 12:52:29.405006910 +0200
51d9a3
+++ strace-5.18/src/defs.h	2022-07-13 12:52:54.532710356 +0200
51d9a3
@@ -785,12 +785,13 @@
51d9a3
 	return pathtrace_match_set(tcp, &global_path_set);
51d9a3
 }
51d9a3
 
51d9a3
-extern int getfdpath_pid(pid_t pid, int fd, char *buf, unsigned bufsize);
51d9a3
+extern int getfdpath_pid(pid_t pid, int fd, char *buf, unsigned bufsize,
51d9a3
+			 bool *deleted);
51d9a3
 
51d9a3
 static inline int
51d9a3
 getfdpath(struct tcb *tcp, int fd, char *buf, unsigned bufsize)
51d9a3
 {
51d9a3
-	return getfdpath_pid(tcp->pid, fd, buf, bufsize);
51d9a3
+	return getfdpath_pid(tcp->pid, fd, buf, bufsize, NULL);
51d9a3
 }
51d9a3
 
51d9a3
 extern unsigned long getfdinode(struct tcb *, int);
51d9a3
Index: strace-5.18/src/largefile_wrappers.h
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/src/largefile_wrappers.h	2022-07-13 12:52:29.405006910 +0200
51d9a3
+++ strace-5.18/src/largefile_wrappers.h	2022-07-13 12:52:48.451782122 +0200
51d9a3
@@ -31,6 +31,7 @@
51d9a3
 #  endif
51d9a3
 #  define fstat_fd fstat64
51d9a3
 #  define strace_stat_t struct stat64
51d9a3
+#  define lstat_file lstat64
51d9a3
 #  define stat_file stat64
51d9a3
 #  define struct_dirent struct dirent64
51d9a3
 #  define read_dir readdir64
51d9a3
@@ -42,6 +43,7 @@
51d9a3
 #  define fcntl_fd fcntl
51d9a3
 #  define fstat_fd fstat
51d9a3
 #  define strace_stat_t struct stat
51d9a3
+#  define lstat_file lstat
51d9a3
 #  define stat_file stat
51d9a3
 #  define struct_dirent struct dirent
51d9a3
 #  define read_dir readdir
51d9a3
Index: strace-5.18/src/pathtrace.c
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/src/pathtrace.c	2022-07-13 12:52:29.405006910 +0200
51d9a3
+++ strace-5.18/src/pathtrace.c	2022-07-13 12:52:54.532710356 +0200
51d9a3
@@ -10,7 +10,11 @@
51d9a3
 #include "defs.h"
51d9a3
 #include <limits.h>
51d9a3
 #include <poll.h>
51d9a3
+#include <sys/stat.h>
51d9a3
+#include <sys/types.h>
51d9a3
+#include <unistd.h>
51d9a3
 
51d9a3
+#include "largefile_wrappers.h"
51d9a3
 #include "number_set.h"
51d9a3
 #include "sen.h"
51d9a3
 #include "xstring.h"
51d9a3
@@ -77,7 +81,7 @@
51d9a3
  * Get path associated with fd of a process with pid.
51d9a3
  */
51d9a3
 int
51d9a3
-getfdpath_pid(pid_t pid, int fd, char *buf, unsigned bufsize)
51d9a3
+getfdpath_pid(pid_t pid, int fd, char *buf, unsigned bufsize, bool *deleted)
51d9a3
 {
51d9a3
 	char linkpath[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
51d9a3
 	ssize_t n;
51d9a3
@@ -91,12 +95,50 @@
51d9a3
 
51d9a3
 	xsprintf(linkpath, "/proc/%u/fd/%u", proc_pid, fd);
51d9a3
 	n = readlink(linkpath, buf, bufsize - 1);
51d9a3
+	if (n < 0)
51d9a3
+		goto end;
51d9a3
+
51d9a3
 	/*
51d9a3
 	 * NB: if buf is too small, readlink doesn't fail,
51d9a3
 	 * it returns truncated result (IOW: n == bufsize - 1).
51d9a3
 	 */
51d9a3
-	if (n >= 0)
51d9a3
-		buf[n] = '\0';
51d9a3
+	buf[n] = '\0';
51d9a3
+	if (deleted)
51d9a3
+		*deleted = false;
51d9a3
+
51d9a3
+	/*
51d9a3
+	 * Try to figure out if the kernel has appended " (deleted)"
51d9a3
+	 * to the end of a potentially unlinked path and set deleted
51d9a3
+	 * if it is the case.
51d9a3
+	 */
51d9a3
+	static const char del_sfx[] = " (deleted)";
51d9a3
+	if ((size_t) n <= sizeof(del_sfx))
51d9a3
+		goto end;
51d9a3
+
51d9a3
+	char *del = buf + n + 1 - sizeof(del_sfx);
51d9a3
+
51d9a3
+	if (memcmp(del, del_sfx, sizeof(del_sfx)))
51d9a3
+		goto end;
51d9a3
+
51d9a3
+	strace_stat_t st_link;
51d9a3
+	strace_stat_t st_path;
51d9a3
+	int rc = stat_file(linkpath, &st_link);
51d9a3
+
51d9a3
+	if (rc)
51d9a3
+		goto end;
51d9a3
+
51d9a3
+	rc = lstat_file(buf, &st_path);
51d9a3
+
51d9a3
+	if (rc ||
51d9a3
+	    (st_link.st_ino != st_path.st_ino) ||
51d9a3
+	    (st_link.st_dev != st_path.st_dev)) {
51d9a3
+		*del = '\0';
51d9a3
+		n = del - buf + 1;
51d9a3
+		if (deleted)
51d9a3
+			*deleted = true;
51d9a3
+	}
51d9a3
+
51d9a3
+end:
51d9a3
 	return n;
51d9a3
 }
51d9a3
 
51d9a3
Index: strace-5.18/src/util.c
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/src/util.c	2022-07-13 12:52:47.989787575 +0200
51d9a3
+++ strace-5.18/src/util.c	2022-07-13 12:52:48.452782111 +0200
51d9a3
@@ -735,12 +735,15 @@
51d9a3
 }
51d9a3
 
51d9a3
 static void
51d9a3
-print_quoted_string_in_angle_brackets(const char *str)
51d9a3
+print_quoted_string_in_angle_brackets(const char *str, const bool deleted)
51d9a3
 {
51d9a3
 	tprints("<");
51d9a3
 	print_quoted_string_ex(str, strlen(str),
51d9a3
 			       QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
51d9a3
 	tprints(">");
51d9a3
+
51d9a3
+	if (deleted)
51d9a3
+		tprints("(deleted)");
51d9a3
 }
51d9a3
 
51d9a3
 void
51d9a3
@@ -749,8 +752,9 @@
51d9a3
 	PRINT_VAL_D(fd);
51d9a3
 
51d9a3
 	char path[PATH_MAX + 1];
51d9a3
+	bool deleted;
51d9a3
 	if (pid > 0 && !number_set_array_is_empty(decode_fd_set, 0)
51d9a3
-	    && getfdpath_pid(pid, fd, path, sizeof(path)) >= 0) {
51d9a3
+	    && getfdpath_pid(pid, fd, path, sizeof(path), &deleted) >= 0) {
51d9a3
 		if (is_number_in_set(DECODE_FD_SOCKET, decode_fd_set) &&
51d9a3
 		    printsocket(tcp, fd, path))
51d9a3
 			goto printed;
51d9a3
@@ -761,7 +765,7 @@
51d9a3
 		    printpidfd(pid, fd, path))
51d9a3
 			goto printed;
51d9a3
 		if (is_number_in_set(DECODE_FD_PATH, decode_fd_set))
51d9a3
-			print_quoted_string_in_angle_brackets(path);
51d9a3
+			print_quoted_string_in_angle_brackets(path, deleted);
51d9a3
 printed:	;
51d9a3
 	}
51d9a3
 
51d9a3
Index: strace-5.18/tests/fchmod.c
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/tests/fchmod.c	2022-07-13 12:52:29.405006910 +0200
51d9a3
+++ strace-5.18/tests/fchmod.c	2022-07-13 12:52:48.452782111 +0200
51d9a3
@@ -35,10 +35,17 @@
51d9a3
 	(void) unlink(sample);
51d9a3
 	int fd = open(sample, O_CREAT|O_RDONLY, 0400);
51d9a3
 	if (fd == -1)
51d9a3
-		perror_msg_and_fail("open");
51d9a3
+		perror_msg_and_fail("open(\"%s\")", sample);
51d9a3
+
51d9a3
+	static const char sample_del[] = "fchmod_sample_file (deleted)";
51d9a3
+	(void) unlink(sample_del);
51d9a3
+	int fd_del = open(sample_del, O_CREAT|O_RDONLY, 0400);
51d9a3
+	if (fd_del == -1)
51d9a3
+		perror_msg_and_fail("open(\"%s\")", sample);
51d9a3
 
51d9a3
 # ifdef YFLAG
51d9a3
 	char *sample_realpath = get_fd_path(fd);
51d9a3
+	char *sample_del_realpath = get_fd_path(fd_del);
51d9a3
 # endif
51d9a3
 
51d9a3
 	const char *sample_secontext = SECONTEXT_FILE(sample);
51d9a3
@@ -56,12 +63,27 @@
51d9a3
 	       sample_secontext,
51d9a3
 	       sprintrc(rc));
51d9a3
 
51d9a3
+	const char *sample_del_secontext = SECONTEXT_FILE(sample_del);
51d9a3
+	rc = syscall(__NR_fchmod, fd_del, 0600);
51d9a3
+# ifdef YFLAG
51d9a3
+	printf("%s%s(%d<%s>%s, 0600) = %s\n",
51d9a3
+# else
51d9a3
+	printf("%s%s(%d%s, 0600) = %s\n",
51d9a3
+# endif
51d9a3
+	       my_secontext, "fchmod",
51d9a3
+	       fd_del,
51d9a3
+# ifdef YFLAG
51d9a3
+	       sample_del_realpath,
51d9a3
+# endif
51d9a3
+	       sample_del_secontext,
51d9a3
+	       sprintrc(rc));
51d9a3
+
51d9a3
 	if (unlink(sample))
51d9a3
-		perror_msg_and_fail("unlink");
51d9a3
+		perror_msg_and_fail("unlink(\"%s\")", sample);
51d9a3
 
51d9a3
 	rc = syscall(__NR_fchmod, fd, 051);
51d9a3
 # ifdef YFLAG
51d9a3
-	printf("%s%s(%d<%s (deleted)>%s, 051) = %s\n",
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 051) = %s\n",
51d9a3
 # else
51d9a3
 	printf("%s%s(%d%s, 051) = %s\n",
51d9a3
 # endif
51d9a3
@@ -73,9 +95,26 @@
51d9a3
 	       sample_secontext,
51d9a3
 	       sprintrc(rc));
51d9a3
 
51d9a3
+	if (unlink(sample_del))
51d9a3
+		perror_msg_and_fail("unlink(\"%s\")", sample_del);
51d9a3
+
51d9a3
+	rc = syscall(__NR_fchmod, fd_del, 051);
51d9a3
+# ifdef YFLAG
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 051) = %s\n",
51d9a3
+# else
51d9a3
+	printf("%s%s(%d%s, 051) = %s\n",
51d9a3
+# endif
51d9a3
+	       my_secontext, "fchmod",
51d9a3
+	       fd_del,
51d9a3
+# ifdef YFLAG
51d9a3
+	       sample_del_realpath,
51d9a3
+# endif
51d9a3
+	       sample_del_secontext,
51d9a3
+	       sprintrc(rc));
51d9a3
+
51d9a3
 	rc = syscall(__NR_fchmod, fd, 004);
51d9a3
 # ifdef YFLAG
51d9a3
-	printf("%s%s(%d<%s (deleted)>%s, 004) = %s\n",
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 004) = %s\n",
51d9a3
 # else
51d9a3
 	printf("%s%s(%d%s, 004) = %s\n",
51d9a3
 # endif
51d9a3
Index: strace-5.18/tests-m32/fchmod.c
51d9a3
===================================================================
51d9a3
--- strace-5.18.orig/tests-m32/fchmod.c	2022-07-13 12:52:29.405006910 +0200
51d9a3
+++ strace-5.18/tests-m32/fchmod.c	2022-07-13 12:52:48.452782111 +0200
51d9a3
@@ -35,10 +35,17 @@
51d9a3
 	(void) unlink(sample);
51d9a3
 	int fd = open(sample, O_CREAT|O_RDONLY, 0400);
51d9a3
 	if (fd == -1)
51d9a3
-		perror_msg_and_fail("open");
51d9a3
+		perror_msg_and_fail("open(\"%s\")", sample);
51d9a3
+
51d9a3
+	static const char sample_del[] = "fchmod_sample_file (deleted)";
51d9a3
+	(void) unlink(sample_del);
51d9a3
+	int fd_del = open(sample_del, O_CREAT|O_RDONLY, 0400);
51d9a3
+	if (fd_del == -1)
51d9a3
+		perror_msg_and_fail("open(\"%s\")", sample);
51d9a3
 
51d9a3
 # ifdef YFLAG
51d9a3
 	char *sample_realpath = get_fd_path(fd);
51d9a3
+	char *sample_del_realpath = get_fd_path(fd_del);
51d9a3
 # endif
51d9a3
 
51d9a3
 	const char *sample_secontext = SECONTEXT_FILE(sample);
51d9a3
@@ -56,12 +63,27 @@
51d9a3
 	       sample_secontext,
51d9a3
 	       sprintrc(rc));
51d9a3
 
51d9a3
+	const char *sample_del_secontext = SECONTEXT_FILE(sample_del);
51d9a3
+	rc = syscall(__NR_fchmod, fd_del, 0600);
51d9a3
+# ifdef YFLAG
51d9a3
+	printf("%s%s(%d<%s>%s, 0600) = %s\n",
51d9a3
+# else
51d9a3
+	printf("%s%s(%d%s, 0600) = %s\n",
51d9a3
+# endif
51d9a3
+	       my_secontext, "fchmod",
51d9a3
+	       fd_del,
51d9a3
+# ifdef YFLAG
51d9a3
+	       sample_del_realpath,
51d9a3
+# endif
51d9a3
+	       sample_del_secontext,
51d9a3
+	       sprintrc(rc));
51d9a3
+
51d9a3
 	if (unlink(sample))
51d9a3
-		perror_msg_and_fail("unlink");
51d9a3
+		perror_msg_and_fail("unlink(\"%s\")", sample);
51d9a3
 
51d9a3
 	rc = syscall(__NR_fchmod, fd, 051);
51d9a3
 # ifdef YFLAG
51d9a3
-	printf("%s%s(%d<%s (deleted)>%s, 051) = %s\n",
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 051) = %s\n",
51d9a3
 # else
51d9a3
 	printf("%s%s(%d%s, 051) = %s\n",
51d9a3
 # endif
51d9a3
@@ -73,9 +95,26 @@
51d9a3
 	       sample_secontext,
51d9a3
 	       sprintrc(rc));
51d9a3
 
51d9a3
+	if (unlink(sample_del))
51d9a3
+		perror_msg_and_fail("unlink(\"%s\")", sample_del);
51d9a3
+
51d9a3
+	rc = syscall(__NR_fchmod, fd_del, 051);
51d9a3
+# ifdef YFLAG
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 051) = %s\n",
51d9a3
+# else
51d9a3
+	printf("%s%s(%d%s, 051) = %s\n",
51d9a3
+# endif
51d9a3
+	       my_secontext, "fchmod",
51d9a3
+	       fd_del,
51d9a3
+# ifdef YFLAG
51d9a3
+	       sample_del_realpath,
51d9a3
+# endif
51d9a3
+	       sample_del_secontext,
51d9a3
+	       sprintrc(rc));
51d9a3
+
51d9a3
 	rc = syscall(__NR_fchmod, fd, 004);
51d9a3
 # ifdef YFLAG
51d9a3
-	printf("%s%s(%d<%s (deleted)>%s, 004) = %s\n",
51d9a3
+	printf("%s%s(%d<%s>(deleted)%s, 004) = %s\n",
51d9a3
 # else
51d9a3
 	printf("%s%s(%d%s, 004) = %s\n",
51d9a3
 # endif