This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] S390: Sync ptrace.h with kernel. [BZ #21539]
- From: Stefan Liebler <stli at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Cc: Florian Weimer <fweimer at redhat dot com>
- Date: Tue, 4 Jul 2017 10:22:04 +0200
- Subject: Re: [PATCH] S390: Sync ptrace.h with kernel. [BZ #21539]
- Authentication-results: sourceware.org; auth=none
- References: <bda685cb-c5c4-ab27-47e0-1e95223275f9@linux.vnet.ibm.com> <20170613200522.GA14306@altlinux.org> <a70194fb-d96c-d22f-7aba-36be9685d421@linux.vnet.ibm.com> <a0750c84-154a-e24c-acfd-4899ce67a1ef@redhat.com>
On 06/30/2017 12:09 PM, Florian Weimer wrote:
On 06/19/2017 03:10 PM, Stefan Liebler wrote:
* sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c:
New file.
The test fails for me like this on s390x:
[root@ibm-z-25 build]# bash testrun.sh misc/tst-ptrace-singleblock
cat /proc/23548/maps
80000000-80004000 r-xp 00000000 fd:00 1883202
/root/build/misc/tst-ptrace-singleblock
80004000-80005000 r--p 00003000 fd:00 1883202
/root/build/misc/tst-ptrace-singleblock
80005000-80006000 rw-p 00004000 fd:00 1883202
/root/build/misc/tst-ptrace-singleblock
2aa00794000-2aa007ba000 r-xp 00000000 fd:00 34794498
/root/build/elf/ld.so
2aa007ba000-2aa007bb000 r--p 00025000 fd:00 34794498
/root/build/elf/ld.so
2aa007bb000-2aa007bd000 rw-p 00026000 fd:00 34794498
/root/build/elf/ld.so
3fffd1e9000-3fffd1ea000 rw-s 00000000 00:04 146001
/dev/zero (deleted)
3fffd1ea000-3fffd1ec000 rw-p 00000000 00:00 0
3fffd1ec000-3fffd38d000 r-xp 00000000 fd:00 34794501
/root/build/libc.so
3fffd38d000-3fffd391000 r--p 001a0000 fd:00 34794501
/root/build/libc.so
3fffd391000-3fffd393000 rw-p 001a4000 fd:00 34794501
/root/build/libc.so
3fffd393000-3fffd39a000 rw-p 00000000 00:00 0
3ffffe62000-3fffff83000 rw-p 00000000 00:00 0
[stack]
child IA: 0x3fffd22ac62 last_break: 0x2aa0079e218
error: ../sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c:111: not
true: ptrace (req_singleblock, pid, NULL, NULL) == 0
The PTRACE_SINGLEBLOCK of the tracer will stop after: brasl %r14,<puts@plt>!
error: 1 test failures
[root@ibm-z-25 build]#
Relevant package versions:
kernel-3.10.0-689.el7.s390x
kernel-headers-3.10.0-689.el7.s390x
devtoolset-6-gcc-6.3.1-3.1.el7.s390x
Please let me know if you need additional information to debug this.
Thanks,
Florian
Uuups. I also see this behaviour on a RHEL 7.3 machine.
We've checked that request 12 wasn't used in s390 kernel for other
meanings as PTRACE_SINGLEBLOCK. But we've missed the fact, that it has
been introduced with kernel 3.15. On older kernels -1 is returned with
errno EIO.
Please have a look at the attached patch. I've adjusted the test:
Now ptrace request 12 is first done with data argument pointing to
a buffer:
-If request 12 is interpreted as PTRACE_GETREGS, it will store the regs
to buffer without an error. Here the test expects that the buffer is
untouched and an error is returned.
-If request 12 is interpreted as PTRACE_SINGLEBLOCK, it will fail
as data argument is no valid signal.
-If request 12 is not implemented, it will also fail.
Afterwards the request 12 is done with zero data argument:
-If the kernel has support for PTRACE_SINGLEBLOCK (then the kernel
header asm/ptrace.h defines this macro), the ptrace call is not allowed
to fail and has to continue the tracee until next taken branch.
-If the kernel has no support for PTRACE_SINGLEBLOCK, the ptrace call
has to fail with EIO. Then I continue the tracee with PTRACE_CONT.
-If the request 12 is interpreted as PTRACE_GETREGS, it will fail too.
It fails with EFAULT on intel / power as data argument is NULL.
According to the man-page: "Unfortunately, under Linux, different
variations of this fault will return EIO or EFAULT more or less
arbitrarily".
But if request 12 is interpreted as PTRACE_GETREGS, the first ptrace
call will touch the buffer which is detected by this test.
Any thoughts?
If this change is okay, I'll commit it.
Thanks.
Stefan
ChangeLog:
* sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c:
Support running on kernels without PTRACE_SINGLEBLOCK.
commit 5e668ce6055d6c690dec773b41c11a801265cd21
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Tue Jul 4 10:20:05 2017 +0200
S390: Fix tst-ptrace-singleblock if kernel does not support PTRACE_SINGLEBLOCK.
The request PTRACE_SINGLEBLOCK was introduced in Linux 3.15. Thus the ptrace call
will fail on older kernels.
Thus the test is now testing PTRACE_SINGLEBLOCK with data argument pointing to a
buffer on stack which is assumed to fail. If the request would be interpreted as
PTRACE_GETREGS, then the ptrace call will not fail and the regs are written to buf.
If we run with a kernel with support for PTRACE_SINGLEBLOCK a ptrace call with
data=NULL, is not allowed to fail. If we run with a kernel without support for
PTRACE_SINGLEBLOCK a ptrace call with data=NULL, has to fail with EIO.
ChangeLog:
* sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c:
Support running on kernels without PTRACE_SINGLEBLOCK.
diff --git a/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c b/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c
index 95a2f55..65858cb 100644
--- a/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c
+++ b/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c
@@ -26,6 +26,8 @@
#include <elf.h>
#include <support/xunistd.h>
#include <support/check.h>
+#include <string.h>
+#include <errno.h>
/* Ensure that we use the PTRACE_SINGLEBLOCK definition from glibc ptrace.h
in tracer_func. We need the kernel ptrace.h for structs ptrace_area
@@ -63,6 +65,10 @@ tracer_func (int pid)
gregset_t regs2;
int status;
+ int ret;
+#define MAX_CHARS_IN_BUF 4096
+ char buf[MAX_CHARS_IN_BUF + 1];
+ size_t buf_count;
while (1)
{
@@ -104,11 +110,67 @@ tracer_func (int pid)
The s390 kernel has no support for PTRACE_GETREGS!
Thus glibc ptrace.h is adjusted to match kernel ptrace.h.
+ The glibc sys/ptrace.h header contains the identifier
+ PTRACE_SINGLEBLOCK in enum __ptrace_request. In contrast, the kernel
+ asm/ptrace.h header defines PTRACE_SINGLEBLOCK.
+
This test ensures, that PTRACE_SINGLEBLOCK defined in glibc
works as expected. If the kernel would interpret it as
PTRACE_GETREGS, then the tracee will not make any progress
- and this testcase will time out. */
- TEST_VERIFY_EXIT (ptrace (req_singleblock, pid, NULL, NULL) == 0);
+ and this testcase will time out or the ptrace call will fail with
+ different errors. */
+
+ /* Ptrace request 12 is first done with data argument pointing to
+ a buffer:
+ -If request 12 is interpreted as PTRACE_GETREGS, it will store the regs
+ to buffer without an error.
+
+ -If request 12 is interpreted as PTRACE_SINGLEBLOCK, it will fail
+ as data argument is used as signal-number and the address of
+ buf is no valid signal.
+
+ -If request 12 is not implemented, it will also fail.
+
+ Here the test expects that the buffer is untouched and an error is
+ returned. */
+ memset (buf, 'a', MAX_CHARS_IN_BUF);
+ ret = ptrace (req_singleblock, pid, NULL, buf);
+ buf [MAX_CHARS_IN_BUF] = '\0';
+ buf_count = strspn (buf, "a");
+ TEST_VERIFY_EXIT (buf_count == MAX_CHARS_IN_BUF);
+ TEST_VERIFY_EXIT (ret == -1);
+
+ /* Ptrace request 12 is done with zero data argument:
+ -If the kernel has support for PTRACE_SINGLEBLOCK (then the kernel
+ header asm/ptrace.h defines this macro), the ptrace call is not allowed
+ to fail and has to continue the tracee until next taken branch.
+
+ -If the kernel (<3.15) has no support for PTRACE_SINGLEBLOCK, the
+ ptrace call has to fail with EIO. Then I continue the tracee with
+ PTRACE_CONT.
+
+ -If the request 12 is interpreted as PTRACE_GETREGS, it will fail too.
+ It fails with EFAULT on intel / power as data argument is NULL.
+ According to the man-page: "Unfortunately, under Linux, different
+ variations of this fault will return EIO or EFAULT more or less
+ arbitrarily".
+ But if request 12 is interpreted as PTRACE_GETREGS, the first ptrace
+ call will touch the buffer which is detected by this test. */
+ errno = 0;
+ ret = ptrace (req_singleblock, pid, NULL, NULL);
+#ifdef PTRACE_SINGLEBLOCK
+ /* The kernel has support for PTRACE_SINGLEBLOCK ptrace request. */
+ TEST_VERIFY_EXIT (errno == 0);
+ TEST_VERIFY_EXIT (ret == 0);
+#else
+ /* The kernel (< 3.15) has no support for PTRACE_SINGLEBLOCK ptrace
+ request. */
+ TEST_VERIFY_EXIT (errno == EIO);
+ TEST_VERIFY_EXIT (ret == -1);
+
+ /* Just continue tracee until it exits normally. */
+ TEST_VERIFY_EXIT (ptrace (PTRACE_CONT, pid, NULL, NULL) == 0);
+#endif
}
}