summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.vnet.ibm.com>2017-07-11 10:37:03 +0200
committerStefan Liebler <stli@linux.vnet.ibm.com>2017-07-11 10:38:44 +0200
commit2c804457879c2dd76823d1b47f1a1eba5073727c (patch)
tree97a2efc167a6bdaa1a7f370102c08d9725a92fc8 /sysdeps
parent38eea35ca7aa8909e2225da15dd5e1f27650ec71 (diff)
downloadglibc-2c804457879c2dd76823d1b47f1a1eba5073727c.tar.gz
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, returns zero with no error. If we run with a kernel without support for PTRACE_SINGLEBLOCK a ptrace call with data=NULL reports an error. In the latter case, the test is just continuing with PTRACE_CONT. ChangeLog: * sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c: Support running on kernels without PTRACE_SINGLEBLOCK.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c b/sysdeps/unix/sysv/linux/s390/tst-ptrace-singleblock.c
index 95a2f55612..c8eea0ad65 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,55 @@ 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);
+
+ /* 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);
+ if (ret == 0)
+ {
+ /* The kernel has support for PTRACE_SINGLEBLOCK ptrace request. */
+ TEST_VERIFY_EXIT (errno == 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);
+ }
}
}