mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-18 12:16:13 +08:00
Add UNSUPPORTED check in elf/tst-pldd.
The testcase forks a child process and runs pldd with PID of this child. On systems where /proc/sys/kernel/yama/ptrace_scope differs from zero, pldd will fail with /usr/bin/pldd: cannot attach to process 3: Operation not permitted This patch checks if ptrace_scope exists, is zero "classic ptrace permissions" or one "restricted ptrace". If ptrace_scope exists and has a higher restriction, then the test is marked as UNSUPPORTED. The case "restricted ptrace" is handled by rearranging the processes involved during the test. Now we have the following process tree: -parent: do_test (performs output checks) --subprocess 1: pldd_process (becomes pldd via execve) ---subprocess 2: target_process (ptraced via pldd) ChangeLog: * elf/tst-pldd.c (do_test): Add UNSUPPORTED check. Rearrange subprocesses. (pldd_process): New function. * support/Makefile (libsupport-routines): Add support_ptrace. * support/xptrace.h: New file. * support/support_ptrace.c: Likewise.
This commit is contained in:
parent
87accae397
commit
2f9046fb05
@ -1,3 +1,12 @@
|
||||
2019-09-18 Stefan Liebler <stli@linux.ibm.com>
|
||||
|
||||
* elf/tst-pldd.c (do_test): Add UNSUPPORTED check.
|
||||
Rearrange subprocesses.
|
||||
(pldd_process): New function.
|
||||
* support/Makefile (libsupport-routines): Add support_ptrace.
|
||||
* support/xptrace.h: New file.
|
||||
* support/support_ptrace.c: Likewise.
|
||||
|
||||
2019-09-17 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/time.c: Remove file.
|
||||
|
@ -30,6 +30,11 @@
|
||||
#include <support/capture_subprocess.h>
|
||||
#include <support/check.h>
|
||||
#include <support/support.h>
|
||||
#include <support/xptrace.h>
|
||||
#include <support/xunistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
static void
|
||||
target_process (void *arg)
|
||||
@ -37,6 +42,34 @@ target_process (void *arg)
|
||||
pause ();
|
||||
}
|
||||
|
||||
static void
|
||||
pldd_process (void *arg)
|
||||
{
|
||||
pid_t *target_pid_ptr = (pid_t *) arg;
|
||||
|
||||
/* Create a copy of current test to check with pldd. As the
|
||||
target_process is a child of this pldd_process, pldd is also able
|
||||
to attach to target_process if YAMA is configured to 1 =
|
||||
"restricted ptrace". */
|
||||
struct support_subprocess target = support_subprocess (target_process, NULL);
|
||||
|
||||
/* Store the pid of target-process as do_test needs it in order to
|
||||
e.g. terminate it at end of the test. */
|
||||
*target_pid_ptr = target.pid;
|
||||
|
||||
/* Three digits per byte plus null terminator. */
|
||||
char pid[3 * sizeof (uint32_t) + 1];
|
||||
snprintf (pid, array_length (pid), "%d", target.pid);
|
||||
|
||||
char *prog = xasprintf ("%s/pldd", support_bindir_prefix);
|
||||
|
||||
/* Run pldd and use the pid of target_process as argument. */
|
||||
execve (prog, (char *const []) { (char *) prog, pid, NULL },
|
||||
(char *const []) { NULL });
|
||||
|
||||
FAIL_EXIT1 ("Returned from execve: errno=%d=%m\n", errno);
|
||||
}
|
||||
|
||||
/* The test runs in a container because pldd does not support tracing
|
||||
a binary started by the loader iself (as with testrun.sh). */
|
||||
|
||||
@ -52,26 +85,23 @@ in_str_list (const char *libname, const char *const strlist[])
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* Create a copy of current test to check with pldd. */
|
||||
struct support_subprocess target = support_subprocess (target_process, NULL);
|
||||
|
||||
/* Run 'pldd' on test subprocess. */
|
||||
struct support_capture_subprocess pldd;
|
||||
/* Check if our subprocess can be debugged with ptrace. */
|
||||
{
|
||||
/* Three digits per byte plus null terminator. */
|
||||
char pid[3 * sizeof (uint32_t) + 1];
|
||||
snprintf (pid, array_length (pid), "%d", target.pid);
|
||||
|
||||
char *prog = xasprintf ("%s/pldd", support_bindir_prefix);
|
||||
|
||||
pldd = support_capture_subprogram (prog,
|
||||
(char *const []) { (char *) prog, pid, NULL });
|
||||
|
||||
support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout);
|
||||
|
||||
free (prog);
|
||||
int ptrace_scope = support_ptrace_scope ();
|
||||
if (ptrace_scope >= 2)
|
||||
FAIL_UNSUPPORTED ("/proc/sys/kernel/yama/ptrace_scope >= 2");
|
||||
}
|
||||
|
||||
pid_t *target_pid_ptr = (pid_t *) xmmap (NULL, sizeof (pid_t),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1);
|
||||
|
||||
/* Run 'pldd' on test subprocess which will be created in pldd_process.
|
||||
The pid of the subprocess will be written to target_pid_ptr. */
|
||||
struct support_capture_subprocess pldd;
|
||||
pldd = support_capture_subprocess (pldd_process, target_pid_ptr);
|
||||
support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout);
|
||||
|
||||
/* Check 'pldd' output. The test is expected to be linked against only
|
||||
loader and libc. */
|
||||
{
|
||||
@ -85,7 +115,7 @@ do_test (void)
|
||||
/* First line is in the form of <pid>: <full path of executable> */
|
||||
TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2);
|
||||
|
||||
TEST_COMPARE (pid, target.pid);
|
||||
TEST_COMPARE (pid, *target_pid_ptr);
|
||||
TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0);
|
||||
|
||||
/* It expects only one loader and libc loaded by the program. */
|
||||
@ -93,7 +123,7 @@ do_test (void)
|
||||
while (fgets (buffer, array_length (buffer), out) != NULL)
|
||||
{
|
||||
/* Ignore vDSO. */
|
||||
if (buffer[0] != '/')
|
||||
if (buffer[0] != '/')
|
||||
continue;
|
||||
|
||||
/* Remove newline so baseline (buffer) can compare against the
|
||||
@ -128,7 +158,9 @@ do_test (void)
|
||||
}
|
||||
|
||||
support_capture_subprocess_free (&pldd);
|
||||
support_process_terminate (&target);
|
||||
if (kill (*target_pid_ptr, SIGKILL) != 0)
|
||||
FAIL_EXIT1 ("Unable to kill target_process: errno=%d=%m\n", errno);
|
||||
xmunmap (target_pid_ptr, sizeof (pid_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ libsupport-routines = \
|
||||
support_format_hostent \
|
||||
support_format_netent \
|
||||
support_isolate_in_subprocess \
|
||||
support_ptrace \
|
||||
support_openpty \
|
||||
support_paths \
|
||||
support_quote_blob \
|
||||
|
44
support/support_ptrace.c
Normal file
44
support/support_ptrace.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* Support functions handling ptrace_scope.
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <support/check.h>
|
||||
#include <support/xstdio.h>
|
||||
#include <support/xptrace.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
int
|
||||
support_ptrace_scope (void)
|
||||
{
|
||||
int ptrace_scope = -1;
|
||||
|
||||
#ifdef __linux__
|
||||
/* YAMA may be not enabled. Otherwise it contains a value from 0 to 3:
|
||||
- 0 classic ptrace permissions
|
||||
- 1 restricted ptrace
|
||||
- 2 admin-only attach
|
||||
- 3 no attach */
|
||||
FILE *f = fopen ("/proc/sys/kernel/yama/ptrace_scope", "r");
|
||||
if (f != NULL)
|
||||
{
|
||||
TEST_COMPARE (fscanf (f, "%d", &ptrace_scope), 1);
|
||||
xfclose (f);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ptrace_scope;
|
||||
}
|
32
support/xptrace.h
Normal file
32
support/xptrace.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* Support functions handling ptrace_scope.
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef SUPPORT_PTRACE_H
|
||||
#define SUPPORT_PTRACE_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Return the current YAMA mode set on the machine (0 to 3) or -1
|
||||
if YAMA is not supported. */
|
||||
int support_ptrace_scope (void);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user