[PATCH] pidfd_getfd: fix decoder
Ákos Uzonyi
uzonyi.akos at gmail.com
Mon Apr 20 23:10:20 UTC 2020
The decoder incorrectly assumed the first argument being a pid,
but actually it is a pidfd.
As of now, the patch does not change behavior, since print_pid_fd
is not really implemented yet (just simply prints the fd).
* defs.h (pidfd_get_pid): New function definition.
* utils.c (pidfd_get_pid): New function, returns the pid of a pidfd.
(printpidfd): Rewritten using pidfd_get_pid.
(printfd): Removed path argument from printpidfd.
* pidfd_getfd.c: Use pidfd_get_pid to get the pid of the pidfd.
Fixes: v5.6~46 "Implement pidfd_getfd syscall decoding"
Signed-off-by: Ákos Uzonyi <uzonyi.akos at gmail.com>
---
defs.h | 1 +
pidfd_getfd.c | 8 +++++++-
util.c | 36 +++++++++++++++++++++++-------------
3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/defs.h b/defs.h
index 0968bc35..504c4eea 100644
--- a/defs.h
+++ b/defs.h
@@ -1027,6 +1027,7 @@ printpath(struct tcb *, kernel_ulong_t addr);
# define TIMESPEC_TEXT_BUFSIZE \
(sizeof(long long) * 3 * 2 + sizeof("{tv_sec=-, tv_nsec=}"))
+extern pid_t pidfd_get_pid(struct tcb *, int);
extern void printfd(struct tcb *, int);
/**
* Print file descriptor fd owned by process with ID pid (from the PID NS
diff --git a/pidfd_getfd.c b/pidfd_getfd.c
index c5c40ae6..b93563a5 100644
--- a/pidfd_getfd.c
+++ b/pidfd_getfd.c
@@ -15,7 +15,13 @@ SYS_FUNC(pidfd_getfd)
printfd(tcp, (int) tcp->u_arg[0]);
/* int fd */
tprints(", ");
- print_pid_fd(tcp, (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
+
+ pid_t pid = pidfd_get_pid(tcp, (int) tcp->u_arg[0]);
+ if (pid >= 0)
+ print_pid_fd(tcp, pid, (int) tcp->u_arg[1]);
+ else
+ tprintf("%d", (int) tcp->u_arg[1]);
+
/* unsigned int flags */
tprintf(", %#x", (unsigned int) tcp->u_arg[2]);
diff --git a/util.c b/util.c
index 0d9de2f6..c7f5d68d 100644
--- a/util.c
+++ b/util.c
@@ -567,43 +567,53 @@ printdev(struct tcb *tcp, int fd, const char *path)
return false;
}
-static bool
-printpidfd(struct tcb *tcp, int fd, const char *path)
+pid_t
+pidfd_get_pid(struct tcb *tcp, int fd)
{
static const char pidfd_path[] = "anon_inode:[pidfd]";
+ char path[PATH_MAX + 1];
+ if (getfdpath(tcp, fd, path, sizeof(path)) < 0)
+ return -1;
+
if (strcmp(path, pidfd_path))
- return false;
+ return -1;
char fdi_path[sizeof("/proc/%u/fdinfo/%u") + 2 * sizeof(int) * 3];
xsprintf(fdi_path, "/proc/%u/fdinfo/%u", tcp->pid, fd);
FILE *f = fopen_stream(fdi_path, "r");
if (!f)
- return false;
+ return -1;
static const char pid_pfx[] = "Pid:\t";
char *line = NULL;
size_t sz = 0;
- bool ret = false;
+ pid_t pid = -1;
while (getline(&line, &sz, f) > 0) {
const char *pos = STR_STRIP_PREFIX(line, pid_pfx);
if (pos == line)
continue;
- int pid = string_to_uint_ex(pos, NULL, INT_MAX, "\n");
- if (pid >= 0) {
- tprintf("pid:%d", pid);
- ret = true;
- }
-
+ pid = string_to_uint_ex(pos, NULL, INT_MAX, "\n");
break;
}
free(line);
fclose(f);
- return ret;
+ return pid;
+}
+
+static bool
+printpidfd(struct tcb *tcp, int fd)
+{
+ int pid = pidfd_get_pid(tcp, fd);
+ if (pid < 0)
+ return false;
+
+ tprintf("pid:%d", pid);
+ return true;
}
void
@@ -620,7 +630,7 @@ printfd(struct tcb *tcp, int fd)
printdev(tcp, fd, path))
goto printed;
if (is_number_in_set(DECODE_FD_PIDFD, decode_fd_set) &&
- printpidfd(tcp, fd, path))
+ printpidfd(tcp, fd))
goto printed;
print_quoted_string_ex(path, strlen(path),
QUOTE_OMIT_LEADING_TRAILING_QUOTES, "<>");
--
2.26.1
More information about the Strace-devel
mailing list