From c62b945324188625c8b55b8fb3f249665de215b3 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Fri, 22 Jun 2018 17:44:41 +0200 Subject: [PATCH] ptrace.2: BUGS: ptrace() may set errno to zero ptrace() with requests PTRACE_PEEKTEXT, PTRACE_PEEKDATA and PTRACE_PEEKUSER can set errno to zero. AFAICS this is for a good reason (so that you can tell the difference between a successful PEEK with a result of -1 and a failed PEEK, even if you forget to clear errno yourself), but it technically violates the rules described in the errno.3 manpage. glibc snippet from sysdeps/unix/sysv/linux/ptrace.c: res = INLINE_SYSCALL (ptrace, 4, request, pid, addr, data); if (res >= 0 && request > 0 && request < 4) { __set_errno (0); return ret; } reproducer: $ cat ptrace_test.c char foobar_data[4] = "ABCD"; int main(void) { pid_t child = fork(); if (child == -1) err(1, "fork"); if (child == 0) { if (prctl(PR_SET_PDEATHSIG, SIGKILL)) err(1, "prctl"); while (1) sleep(1); } int status; if (ptrace(PTRACE_ATTACH, child, NULL, NULL)) err(1, "attach"); if (waitpid(child, &status, 0) != child) err(1, "wait"); errno = EINVAL; unsigned int res = ptrace(PTRACE_PEEKDATA, child, foobar_data, NULL); printf("errno after PEEKDATA: %d\n", errno); printf("PEEKDATA result: 0x%x\n", res); } $ gcc -o ptrace_test ptrace_test.c -Wall $ ./ptrace_test errno after PEEKDATA: 0 PEEKDATA result: 0x44434241 Signed-off-by: Jann Horn Signed-off-by: Michael Kerrisk --- man2/ptrace.2 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/man2/ptrace.2 b/man2/ptrace.2 index 536607f12..6e4175f35 100644 --- a/man2/ptrace.2 +++ b/man2/ptrace.2 @@ -2777,6 +2777,12 @@ again. errors may behave in an unintended way upon an .BR strace (1) attach.) +.PP +Contrary to the normal rules, the glibc wrapper for +.BR ptrace () +can set +.I errno +to zero. .SH SEE ALSO .BR gdb (1), .BR ltrace (1),