mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 16:35:02 +01:00
[This commit is taken from commits 6391, 6401, and 6402 of the internal tree.]
tonyj: - Verify long path (d_path) error checking. (6391) - Better ptrace tests. (6401) - Confined mount tests require cap_sys_admin to even get to the confined checks. (6402)
This commit is contained in:
parent
6fda1df1a6
commit
92c9c8732d
6 changed files with 537 additions and 36 deletions
|
@ -7,17 +7,54 @@
|
|||
# published by the Free Software Foundation, version 2 of the
|
||||
# License.
|
||||
|
||||
SRC=access.c changehat.c changehat_fork.c changehat_misc.c changehat_misc2.c \
|
||||
changehat_twice.c changehat_fail.c changehat_wrapper.c changehat_pthread.c \
|
||||
chdir.c chgrp.c chmod.c chown.c \
|
||||
exec.c exec_qual.c exec_qual2.c fork.c link.c mmap.c \
|
||||
mkdir.c mount.c named_pipe.c net_raw.c open.c pipe.c pwrite.c rename.c \
|
||||
readdir.c rw.c syscall_mknod.c swap.c syscall_chroot.c \
|
||||
SRC=access.c \
|
||||
changehat.c \
|
||||
changehat_fork.c \
|
||||
changehat_misc.c \
|
||||
changehat_misc2.c \
|
||||
changehat_twice.c \
|
||||
changehat_fail.c \
|
||||
changehat_wrapper.c \
|
||||
changehat_pthread.c \
|
||||
chdir.c \
|
||||
chgrp.c \
|
||||
chmod.c \
|
||||
chown.c \
|
||||
deleted.c \
|
||||
exec.c \
|
||||
exec_qual.c \
|
||||
exec_qual2.c \
|
||||
fork.c \
|
||||
link.c \
|
||||
mmap.c \
|
||||
mkdir.c \
|
||||
mount.c \
|
||||
named_pipe.c \
|
||||
net_raw.c \
|
||||
open.c \
|
||||
pipe.c \
|
||||
ptrace.c \
|
||||
ptrace_helper.c \
|
||||
pwrite.c \
|
||||
rename.c \
|
||||
readdir.c \
|
||||
rw.c \
|
||||
syscall_mknod.c \
|
||||
swap.c \
|
||||
syscall_chroot.c \
|
||||
syscall_mlockall.c \
|
||||
syscall_ptrace.c syscall_reboot.c syscall_setpriority.c \
|
||||
syscall_sethostname.c syscall_setdomainname.c syscall_setscheduler.c \
|
||||
syscall_sysctl.c tcp.c unix_fd_client.c unix_fd_server.c unlink.c \
|
||||
deleted.c xattrs.c
|
||||
syscall_ptrace.c \
|
||||
syscall_reboot.c \
|
||||
syscall_setpriority.c \
|
||||
syscall_sethostname.c \
|
||||
syscall_setdomainname.c \
|
||||
syscall_setscheduler.c \
|
||||
syscall_sysctl.c \
|
||||
tcp.c \
|
||||
unix_fd_client.c \
|
||||
unix_fd_server.c \
|
||||
unlink.c \
|
||||
xattrs.c
|
||||
|
||||
#only do the ioperm/iopl tests for x86 derived architectures
|
||||
ifneq (,$(findstring $(shell uname -i),i386 i486 i586 i686 x86 x86_64))
|
||||
|
@ -56,10 +93,38 @@ CFLAGS+=$(CHANGEHAT_FLAGS) $(LIBIMMUNIX) -Wall -Wstrict-prototypes
|
|||
|
||||
EXEC=$(SRC:%.c=%)
|
||||
|
||||
TESTS=access capabilities changehat changehat_fork changehat_misc chdir exec \
|
||||
exec_qual fork i18n link mkdir mmap mount mult_mount named_pipe net_raw \
|
||||
open pipe ptrace pwrite regex rename readdir rw swap sd_flags setattr \
|
||||
syscall unix_fd_server unlink deleted xattrs
|
||||
TESTS=access \
|
||||
capabilities \
|
||||
changehat \
|
||||
changehat_fork \
|
||||
changehat_misc \
|
||||
chdir \
|
||||
deleted \
|
||||
exec \
|
||||
exec_qual \
|
||||
fork \
|
||||
i18n \
|
||||
link \
|
||||
mkdir \
|
||||
mmap \
|
||||
mount \
|
||||
mult_mount \
|
||||
named_pipe \
|
||||
net_raw \
|
||||
open pipe \
|
||||
ptrace \
|
||||
pwrite \
|
||||
regex \
|
||||
rename \
|
||||
readdir \
|
||||
rw \
|
||||
swap \
|
||||
sd_flags \
|
||||
setattr \
|
||||
syscall \
|
||||
unix_fd_server \
|
||||
unlink\
|
||||
xattrs
|
||||
|
||||
all: $(EXEC) changehat.h
|
||||
# This is sadly needed for buildbot, which has a restrictive umask.
|
||||
|
@ -68,6 +133,9 @@ all: $(EXEC) changehat.h
|
|||
changehat_pthread: changehat_pthread.c changehat.h
|
||||
${CC} ${CFLAGS} -lpthread -o $@ $<
|
||||
|
||||
ptrace_helper: ptrace_helper.c
|
||||
$(CC) -o $@ $<
|
||||
|
||||
tests: all
|
||||
@if [ `whoami` == "root" ] ;\
|
||||
then \
|
||||
|
|
169
tests/regression/subdomain/longpath.sh
Normal file
169
tests/regression/subdomain/longpath.sh
Normal file
|
@ -0,0 +1,169 @@
|
|||
#! /bin/bash
|
||||
# $Id: open.sh 6040 2006-01-11 00:15:48Z tonyj $
|
||||
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, version 2 of the
|
||||
# License.
|
||||
|
||||
#=NAME longpath
|
||||
#=DESCRIPTION
|
||||
# Verify handling of long pathnames.
|
||||
#=END
|
||||
|
||||
genrandname()
|
||||
{
|
||||
_goal=$1
|
||||
_ascii="abcdefghijlkmnopqrstuvwxyz0123456789"
|
||||
_mod=${#_ascii}
|
||||
_i=0
|
||||
|
||||
for _i in `seq 2 $_goal`
|
||||
do
|
||||
_c=$((RANDOM % $_mod))
|
||||
_s="${_s}${_ascii:$_c:1}"
|
||||
done
|
||||
|
||||
echo $_s
|
||||
}
|
||||
pwd=`dirname $0`
|
||||
pwd=`cd $pwd ; /bin/pwd`
|
||||
|
||||
bin=$pwd
|
||||
|
||||
. $bin/prologue.inc
|
||||
|
||||
name_max=255 #NAME_MAX
|
||||
direlem_max=235 #Length for intermediate dirs, slightly less than name_max
|
||||
buf_max=4096 #PAGE
|
||||
|
||||
# generate 255 character filename
|
||||
file=`genrandname $name_max`
|
||||
file2=`genrandname $name_max`
|
||||
|
||||
settest open
|
||||
okperm=rw
|
||||
linkperm=rwl
|
||||
|
||||
cd $tmpdir
|
||||
|
||||
mkdir_expected_fail=0
|
||||
file_expected_fail=0
|
||||
link_expected_fail=0
|
||||
|
||||
iter=1
|
||||
while true
|
||||
do
|
||||
direlem=`genrandname $direlem_max`
|
||||
|
||||
_dpath=`pwd`/$direlem
|
||||
|
||||
if [ ${#_dpath} -lt 4096 ]
|
||||
then
|
||||
dstatus=pass
|
||||
else
|
||||
dstatus=fail
|
||||
fi
|
||||
|
||||
settest mkdir
|
||||
genprofile $tmpdir/**:$okperm
|
||||
runchecktest "LONGPATH MKDIR ($iter)" $dstatus mkdir $direlem
|
||||
|
||||
if [ $dstatus = "pass" ]
|
||||
then
|
||||
if [ -d $direlem ]
|
||||
then
|
||||
#echo "mkdir ($iter) passed at length ${#_dpath}"
|
||||
cd $direlem
|
||||
else
|
||||
echo "FAIL: $direlem ($_iter) was not created" >&2
|
||||
fi
|
||||
else
|
||||
if [ -d $direlem ]
|
||||
then
|
||||
echo "mkdir ($iter) incorrectly generated dir at length ${#_dpath}"
|
||||
else
|
||||
#echo "mkdir ($iter) failed at length ${#_dpath}"
|
||||
mkdir_expected_fail=1
|
||||
fi
|
||||
:
|
||||
fi
|
||||
|
||||
_fpath=`pwd`/$file
|
||||
if [ ${#_fpath} -lt 4096 ]
|
||||
then
|
||||
fstatus=pass
|
||||
else
|
||||
fstatus=fail
|
||||
fi
|
||||
|
||||
settest open
|
||||
genprofile $tmpdir/**:$okperm
|
||||
runchecktest "LONGPATH CREATE ($iter)" $fstatus $file
|
||||
|
||||
if [ $fstatus = "pass" ]
|
||||
then
|
||||
if [ -f $file ]
|
||||
then
|
||||
#echo "file creat ($iter) passed at length ${#_dpath}"
|
||||
:
|
||||
else
|
||||
echo "FAIL: $file ($_iter) was not created" >&2
|
||||
fi
|
||||
elif [ $fstatus = "fail" ]
|
||||
then
|
||||
if [ -f $file ]
|
||||
then
|
||||
echo "file creat ($iter) incorrectly generated file at length ${#_fpath}"
|
||||
else
|
||||
#echo "file creat ($iter) failed at length ${#_fpath}"
|
||||
file_expected_fail=1
|
||||
fi
|
||||
fi
|
||||
|
||||
settest link
|
||||
genprofile $tmpdir/**:$linkperm
|
||||
if [ -f $file ]
|
||||
then
|
||||
_f=$file
|
||||
elif [ -f ../$file ]
|
||||
then
|
||||
_f=../$file
|
||||
else
|
||||
echo "unable to find file to link" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
runchecktest "LONGPATH LINK ($iter)" $fstatus $_f $file2
|
||||
|
||||
if [ $fstatus = "pass" ]
|
||||
then
|
||||
if [ -f $file2 ]
|
||||
then
|
||||
#echo "file link ($iter) passed at length ${#_dpath}"
|
||||
:
|
||||
else
|
||||
echo "FAIL: $file2 ($_iter) was not linked" >&2
|
||||
fi
|
||||
elif [ $fstatus = "fail" ]
|
||||
then
|
||||
if [ -f $file2 ]
|
||||
then
|
||||
echo "file link ($iter) incorrectly generated file at length ${#_dpath}"
|
||||
else
|
||||
#echo "file link ($iter) failed at length ${#_fpath}"
|
||||
link_expected_fail=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $mkdir_expected_fail -eq 1 -a \
|
||||
$file_expected_fail -eq 1 -a \
|
||||
$link_expected_fail -eq 1 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
|
||||
: $((iter++))
|
||||
done
|
|
@ -65,7 +65,7 @@ runchecktest "UMOUNT (unconfined)" pass umount ${loop_device} ${mount_point}
|
|||
|
||||
# TEST A2. confine MOUNT
|
||||
|
||||
genprofile
|
||||
genprofile capability:sys_admin
|
||||
runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point}
|
||||
|
||||
# TEST A3. confine UMOUNT
|
||||
|
|
187
tests/regression/subdomain/ptrace.c
Normal file
187
tests/regression/subdomain/ptrace.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <signal.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#define NUM_CHLD_SYSCALLS 10
|
||||
|
||||
#define RET_FAILURE 0
|
||||
#define RET_SUCCESS 1
|
||||
#define RET_CHLD_SUCCESS 2
|
||||
#define RET_CHLD_FAILURE 3
|
||||
#define RET_CHLD_SIGNAL 4
|
||||
|
||||
#define PARENT_TRACE 0
|
||||
#define CHILD_TRACE 1
|
||||
#define HELPER_TRACE 2
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int interp_status(int status)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == 0) {
|
||||
rc = RET_CHLD_SUCCESS;
|
||||
} else {
|
||||
rc = RET_CHLD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
rc = RET_CHLD_SIGNAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int do_parent(pid_t pid, int trace, int num_syscall)
|
||||
{
|
||||
struct user_regs_struct regs;
|
||||
int status, i;
|
||||
|
||||
if (trace) {
|
||||
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_ATTACH) failed - ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this sends a child SIGSTOP */
|
||||
}
|
||||
|
||||
while (wait(&status) != pid);
|
||||
|
||||
if (!WIFSTOPPED(status))
|
||||
return interp_status(status);
|
||||
|
||||
for (i=0;i<num_syscall * 2;i++){
|
||||
/* this will restart stopped child */
|
||||
if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_SINGLESTEP) failed - ");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
|
||||
while (wait(&status) != pid);
|
||||
|
||||
if (!WIFSTOPPED(status))
|
||||
return interp_status(status);
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_DETACH) failed - ");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
|
||||
int do_child(char *argv[], int child_trace, int helper)
|
||||
{
|
||||
if (helper) {
|
||||
if (child_trace) {
|
||||
putenv("_tracer=child");
|
||||
} else {
|
||||
putenv("_tracer=parent");
|
||||
}
|
||||
} else {
|
||||
if (child_trace) {
|
||||
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1){
|
||||
perror("FAIL: child ptrace(PTRACE_TRACEME) failed - ");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (raise(SIGSTOP) != 0){
|
||||
perror("FAIL: child SIGSTOP itself failed -");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
/* ok were stopped, wait for parent to trace (continue) us */
|
||||
}
|
||||
|
||||
execve(argv[0], argv, environ);
|
||||
|
||||
perror("FAIL: child exec failed - ");
|
||||
|
||||
return RET_FAILURE;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
int parent_trace = 1,
|
||||
use_helper = 0,
|
||||
num_syscall = NUM_CHLD_SYSCALLS,
|
||||
opt;
|
||||
const char *usage="usage: %s [-c] [-n #syscall] program [args ...]";
|
||||
char **args;
|
||||
|
||||
opterr=0;
|
||||
while (1) {
|
||||
opt=getopt(argc, argv, "chn:");
|
||||
|
||||
if (opt == -1)
|
||||
break;
|
||||
switch (opt) {
|
||||
case 'c': parent_trace = 0;
|
||||
break;
|
||||
case 'h': use_helper = 1;
|
||||
break;
|
||||
case 'n': num_syscall = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, usage, argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, usage, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
args=&argv[optind];
|
||||
|
||||
pid = fork();
|
||||
if (pid > 0){ /*parent */
|
||||
int stat, ret;
|
||||
|
||||
ret = do_parent(pid, parent_trace, num_syscall);
|
||||
|
||||
kill(pid, SIGKILL);
|
||||
|
||||
if (ret < RET_CHLD_SUCCESS) {
|
||||
/* wait for child */
|
||||
while (wait(&stat) != pid);
|
||||
}
|
||||
|
||||
if (ret == RET_FAILURE) {
|
||||
fprintf(stderr, "FAIL: parent failed\n");
|
||||
} else if (ret == RET_CHLD_SUCCESS ||
|
||||
(ret == RET_SUCCESS && WIFSIGNALED(stat) && WTERMSIG(stat) == SIGKILL)) {
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
} else if (ret == RET_CHLD_SIGNAL) {
|
||||
fprintf(stderr, "FAIL: child killed\n");
|
||||
} else {
|
||||
fprintf(stderr, "FAIL: child failed\n");
|
||||
}
|
||||
} else if (pid == 0) { /* child */
|
||||
if (do_child(args, !parent_trace, use_helper))
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
perror("FAIL: fork failed - ");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#! /bin/bash
|
||||
# $Id: ptrace.sh 6040 2006-01-11 00:15:48Z tonyj $
|
||||
# $Id$
|
||||
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
|
@ -10,10 +10,9 @@
|
|||
|
||||
#=NAME ptrace
|
||||
#=DESCRIPTION
|
||||
# Read permission is required for a confined process to be able to be traced
|
||||
# using ptrace. This test verifies this. Currently is it not functioning
|
||||
# correctly. It stopped functioning correctly somewhere between 2.4.18 and
|
||||
# 2.4.20.
|
||||
# Verify ptrace. The tracing process (attacher or parent of ptrace_me) may
|
||||
# not be confined.
|
||||
#
|
||||
#=END
|
||||
|
||||
pwd=`dirname $0`
|
||||
|
@ -23,26 +22,59 @@ bin=$pwd
|
|||
|
||||
. $bin/prologue.inc
|
||||
|
||||
file=$tmpdir/file
|
||||
traceperm=rix
|
||||
notraceperm=ix
|
||||
openperm=rw
|
||||
# Disabled tests:
|
||||
# Tests 3b and 4b
|
||||
# Read permission was required for a confined process to be able to be traced
|
||||
# using ptrace. This stopped being required or functioning correctly
|
||||
# somewhere between 2.4.18 and 2.4.20.
|
||||
#
|
||||
# Tests 10 and 11
|
||||
# Requires a patch which prevents confined traced task from attempting exec.
|
||||
# Unsure of usefulness of this. We are concerned about confined task being
|
||||
# the tracer not the tracee
|
||||
|
||||
touch $file
|
||||
# Test Matrix:
|
||||
# 1. unconfined parent, unconfined child, parent attaches PASS
|
||||
# 2. unconfined parent, unconfined child, child requests tracing PASS
|
||||
# 3a. unconfined parent, confined child (r), parent attaches PASS
|
||||
# 4a. unconfined parent, confined child (r), child requests tracing PASS
|
||||
# 3b. unconfined parent, confined child (!r), parent attaches FAIL
|
||||
# 4b. unconfined parent, confined child (!r), child requests tracing FAIL
|
||||
# 5. confined parent, unconfined child, parent attaches FAIL
|
||||
# 6. confined parent, unconfined child, child requests tracing FAIL
|
||||
# 7. confined parent, confined child, parent attaches FAIL
|
||||
# 8. confined parent, confined child, child requests tracing FAIL
|
||||
# 9. unconfined traced task attempts exec PASS
|
||||
# 10. confined traced task attempts exec unconfined FAIL
|
||||
# 11. confined traced task attempts exec confined FAIL
|
||||
|
||||
# PASS TEST, no confinement
|
||||
settest open
|
||||
helper=$pwd/ptrace_helper
|
||||
|
||||
runchecktest "STRACE OPEN (no confinement)" pass $file
|
||||
runchecktest "test 1" pass -n 100 /bin/true
|
||||
runchecktest "test 2" pass -c -n 100 /bin/true
|
||||
|
||||
# PASS TEST, with rx confinement
|
||||
settest open "$bin/strace.sh {}"
|
||||
genprofile $test:$traceperm $file:$openperm
|
||||
genprofile image=$helper
|
||||
runchecktest "test 3a" pass -h -n 100 $helper
|
||||
runchecktest "test 4a" pass -h -n 100 -c $helper
|
||||
|
||||
runchecktest "STRACE OPEN ($traceperm confinement)" pass $file
|
||||
# lack of 'r' perm is currently not working
|
||||
#genprofile image=ix$helper
|
||||
#runchecktest "test 3b" pass -h -n 100 $helper
|
||||
#runchecktest "test 4b" pass -h -n 100 -c $helper
|
||||
|
||||
# FAIL TEST, with x confinement
|
||||
settest open "$bin/strace.sh {}"
|
||||
genprofile $test:$notraceperm $file:$openperm
|
||||
genprofile $helper:ux
|
||||
runchecktest "test 5" fail -h -n 100 $helper
|
||||
runchecktest "test 6" fail -h -n 100 -c $helper
|
||||
|
||||
runchecktest "STRACE OPEN ($notraceperm confinement)" fail $file
|
||||
genprofile $helper:px -- image=$helper
|
||||
runchecktest "test 7" fail -h -n 100 $helper
|
||||
runchecktest "test 8" fail -h -n 100 -c $helper
|
||||
|
||||
genprofile image=/bin/true
|
||||
runchecktest "test 9" pass -- /bin/bash -c /bin/true
|
||||
|
||||
#genprofile image=$helper /bin/true:ux
|
||||
#runchecktest "test 10" fail -h -n 100 $helper /bin/true
|
||||
|
||||
#genprofile image=$helper /bin/true:rix
|
||||
#runchecktest "test 11" fail -h -n 1000 $helper /bin/true
|
||||
|
|
45
tests/regression/subdomain/ptrace_helper.c
Normal file
45
tests/regression/subdomain/ptrace_helper.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
#define RET_FAILURE 0
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char **args=&argv[1];
|
||||
char *tracer = getenv("_tracer");
|
||||
extern char **environ;
|
||||
int child_traces;
|
||||
|
||||
if (tracer && strcmp(tracer, "parent") == 0) {
|
||||
child_traces = 0;
|
||||
} else if (tracer && strcmp(tracer, "child") == 0) {
|
||||
child_traces = 1;
|
||||
} else {
|
||||
fprintf(stderr, "No/invalid _tracer in environ\n");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
|
||||
if (child_traces == 1 &&
|
||||
ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1){
|
||||
perror("FAIL: child/helper ptrace(PTRACE_TRACEME) failed - ");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
|
||||
if (raise(SIGSTOP) != 0){
|
||||
perror("FAIL: child/helper SIGSTOP itself failed -");
|
||||
return RET_FAILURE;
|
||||
}
|
||||
/* ok were stopped, wait for parent to trace (continue) us */
|
||||
|
||||
if (*args) {
|
||||
execve(args[0], args, environ);
|
||||
} else {
|
||||
for (;;) kill(getpid(), 0);
|
||||
}
|
||||
|
||||
return RET_FAILURE;
|
||||
}
|
Loading…
Add table
Reference in a new issue