ptrace.patch

This commit is contained in:
John Johansen 2007-12-23 01:00:33 +00:00
parent 5b61f80b97
commit 93d88ebfd4
5 changed files with 55 additions and 44 deletions

View file

@ -66,7 +66,7 @@ net_raw_net_raw=TRUE
# we completely disable ptrace(), but it's not clear if we should allow it # we completely disable ptrace(), but it's not clear if we should allow it
# when the sys_ptrace cap is specified. # when the sys_ptrace cap is specified.
# syscall_ptrace_sys_ptrace=TRUE syscall_ptrace_sys_ptrace=TRUE
# if a test case requires arguments, add them here. # if a test case requires arguments, add them here.
syscall_reboot_args=off syscall_reboot_args=off
@ -75,9 +75,11 @@ syscall_setdomainname_args=dumb.example.com
syscall_ioperm_args="0 0x3ff" syscall_ioperm_args="0 0x3ff"
syscall_iopl_args=3 syscall_iopl_args=3
syscall_chroot_args=${tmpdir} syscall_chroot_args=${tmpdir}
syscall_ptrace_args=sub
# if a testcase requires extra subdomain rules, add them here # if a testcase requires extra subdomain rules, add them here
syscall_chroot_extra_entries="/:r ${tmpdir}:r" syscall_chroot_extra_entries="/:r ${tmpdir}:r"
syscall_ptrace_extra_entries="hat:sub"
testwrapper=changehat_wrapper testwrapper=changehat_wrapper

View file

@ -7,15 +7,10 @@
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <signal.h> #include <signal.h>
#include <sys/user.h> #include <sys/user.h>
#include <errno.h>
#define NUM_CHLD_SYSCALLS 10 #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 PARENT_TRACE 0
#define CHILD_TRACE 1 #define CHILD_TRACE 1
#define HELPER_TRACE 2 #define HELPER_TRACE 2
@ -28,17 +23,21 @@ int interp_status(int status)
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) { if (WEXITSTATUS(status) == 0) {
rc = RET_CHLD_SUCCESS; // rc = RET_CHLD_SUCCESS;
rc = 0;
} else { } else {
rc = RET_CHLD_FAILURE; // rc = RET_CHLD_FAILURE;
rc = -WEXITSTATUS(status);
} }
} else { } else {
rc = RET_CHLD_SIGNAL; // rc = RET_CHLD_SIGNAL;
rc = -ECONNABORTED; /* overload to mean child signal */
} }
return rc; return rc;
} }
/* return 0 on success. Child failure -errorno, parent failure errno */
int do_parent(pid_t pid, int trace, int num_syscall) int do_parent(pid_t pid, int trace, int num_syscall)
{ {
struct user regs; struct user regs;
@ -48,13 +47,13 @@ int do_parent(pid_t pid, int trace, int num_syscall)
rc = alarm(5); rc = alarm(5);
if (rc != 0) { if (rc != 0) {
fprintf(stderr, "FAIL: unexpected alarm already set\n"); fprintf(stderr, "FAIL: unexpected alarm already set\n");
return 0; return errno;
} }
if (trace) { if (trace) {
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) { if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("FAIL: parent ptrace(PTRACE_ATTACH) failed - "); perror("FAIL: parent ptrace(PTRACE_ATTACH) failed - ");
return 0; return errno;
} }
/* this sends a child SIGSTOP */ /* this sends a child SIGSTOP */
@ -69,7 +68,7 @@ int do_parent(pid_t pid, int trace, int num_syscall)
/* this will restart stopped child */ /* this will restart stopped child */
if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) == -1) { if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) == -1) {
perror("FAIL: parent ptrace(PTRACE_SINGLESTEP) failed - "); perror("FAIL: parent ptrace(PTRACE_SINGLESTEP) failed - ");
return RET_FAILURE; return errno;
} }
while (wait(&status) != pid); while (wait(&status) != pid);
@ -80,18 +79,19 @@ int do_parent(pid_t pid, int trace, int num_syscall)
memset(&regs, 0, sizeof(regs)); memset(&regs, 0, sizeof(regs));
if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) == -1) { if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) == -1) {
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - "); perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
return RET_FAILURE; return errno;
} }
} }
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) { if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
perror("FAIL: parent ptrace(PTRACE_DETACH) failed - "); perror("FAIL: parent ptrace(PTRACE_DETACH) failed - ");
return RET_FAILURE; return errno;
} }
return RET_SUCCESS; return 0;
} }
/* returns 0 on success or error code of failure */
int do_child(char *argv[], int child_trace, int helper) int do_child(char *argv[], int child_trace, int helper)
{ {
if (helper) { if (helper) {
@ -104,13 +104,13 @@ int do_child(char *argv[], int child_trace, int helper)
if (child_trace) { if (child_trace) {
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1){ if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1){
perror("FAIL: child ptrace(PTRACE_TRACEME) failed - "); perror("FAIL: child ptrace(PTRACE_TRACEME) failed - ");
return RET_FAILURE; return errno;
} }
} }
if (raise(SIGSTOP) != 0){ if (raise(SIGSTOP) != 0){
perror("FAIL: child SIGSTOP itself failed -"); perror("FAIL: child SIGSTOP itself failed -");
return RET_FAILURE; return errno;
} }
/* ok were stopped, wait for parent to trace (continue) us */ /* ok were stopped, wait for parent to trace (continue) us */
} }
@ -119,7 +119,7 @@ int do_child(char *argv[], int child_trace, int helper)
perror("FAIL: child exec failed - "); perror("FAIL: child exec failed - ");
return RET_FAILURE; return errno;
} }
void sigalrm_handler(int sig) { void sigalrm_handler(int sig) {
@ -133,7 +133,8 @@ int main(int argc, char *argv[])
int parent_trace = 1, int parent_trace = 1,
use_helper = 0, use_helper = 0,
num_syscall = NUM_CHLD_SYSCALLS, num_syscall = NUM_CHLD_SYSCALLS,
opt; opt,
ret = 0;
const char *usage = "usage: %s [-c] [-n #syscall] program [args ...]\n"; const char *usage = "usage: %s [-c] [-n #syscall] program [args ...]\n";
char **args; char **args;
@ -170,27 +171,29 @@ int main(int argc, char *argv[])
pid = fork(); pid = fork();
if (pid > 0){ /*parent */ if (pid > 0){ /*parent */
int stat, ret; int stat;
ret = do_parent(pid, parent_trace, num_syscall); ret = do_parent(pid, parent_trace, num_syscall);
kill(pid, SIGKILL); kill(pid, SIGKILL);
if (ret < RET_CHLD_SUCCESS) { if (ret >= 0) {
/* wait for child */ /* wait for child */
while (wait(&stat) != pid); while (wait(&stat) != pid);
} }
if (ret == RET_FAILURE) { if (ret > 0) {
fprintf(stderr, "FAIL: parent failed\n"); perror("FAIL: parent failed: ");
} else if (ret == RET_CHLD_SUCCESS || } else if (ret == 0) { //||
(ret == RET_SUCCESS && WIFSIGNALED(stat) && WTERMSIG(stat) == SIGKILL)) { // (ret == RET_SUCCESS && WIFSIGNALED(stat) && WTERMSIG(stat) == SIGKILL)) {
printf("PASS\n"); printf("PASS\n");
return 0; return 0;
} else if (ret == RET_CHLD_SIGNAL) { } else if (ret == -ECONNABORTED) {
fprintf(stderr, "FAIL: child killed\n"); errno = -ret;
perror("FAIL: child killed: ");
} else { } else {
fprintf(stderr, "FAIL: child failed\n"); errno = -ret;
perror("FAIL: child failed: ");
} }
} else if (pid == 0) { /* child */ } else if (pid == 0) { /* child */
if (do_child(args, !parent_trace, use_helper)) if (do_child(args, !parent_trace, use_helper))
@ -200,5 +203,5 @@ int main(int argc, char *argv[])
perror("FAIL: fork failed - "); perror("FAIL: fork failed - ");
} }
return 1; return ret;
} }

View file

@ -28,10 +28,6 @@ bin=$pwd
# using ptrace. This stopped being required or functioning correctly # using ptrace. This stopped being required or functioning correctly
# somewhere between 2.4.18 and 2.4.20. # 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
# Test Matrix: # Test Matrix:
# 1. unconfined parent, unconfined child, parent attaches PASS # 1. unconfined parent, unconfined child, parent attaches PASS
@ -58,9 +54,9 @@ runchecktest "test 3a" pass -h -n 100 $helper
runchecktest "test 4a" pass -h -n 100 -c $helper runchecktest "test 4a" pass -h -n 100 -c $helper
# lack of 'r' perm is currently not working # lack of 'r' perm is currently not working
#genprofile image=ix$helper genprofile image=ix$helper
#runchecktest "test 3b" pass -h -n 100 $helper runchecktest "test 3b" pass -h -n 100 $helper
#runchecktest "test 4b" pass -h -n 100 -c $helper runchecktest "test 4b" pass -h -n 100 -c $helper
genprofile $helper:ux genprofile $helper:ux
runchecktest "test 5" fail -h -n 100 $helper runchecktest "test 5" fail -h -n 100 $helper
@ -73,8 +69,8 @@ runchecktest "test 8" fail -h -n 100 -c $helper
genprofile image=/bin/true genprofile image=/bin/true
runchecktest "test 9" pass -- /bin/bash -c /bin/true runchecktest "test 9" pass -- /bin/bash -c /bin/true
#genprofile image=$helper /bin/true:ux genprofile image=$helper /bin/true:ux
#runchecktest "test 10" fail -h -n 100 $helper /bin/true runchecktest "test 10" fail -h -n 100 $helper /bin/true
#genprofile image=$helper /bin/true:rix genprofile image=$helper /bin/true:rix
#runchecktest "test 11" fail -h -n 1000 $helper /bin/true runchecktest "test 11" fail -h -n 2000 $helper /bin/true

View file

@ -28,12 +28,12 @@ bin=$pwd
settest syscall_ptrace settest syscall_ptrace
# TEST A1 # TEST A1
runchecktest "PTRACE with no profile" pass runchecktest "PTRACE with no profile" pass sub
# TEST A2. ptrace will fail # TEST A2. ptrace will fail
genprofile genprofile
runchecktest "PTRACE with confinement" fail runchecktest "PTRACE with confinement" fail sub
## ##
## B. MKNOD ## B. MKNOD

View file

@ -21,6 +21,8 @@
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include "changehat.h"
#define FALSE 0 #define FALSE 0
#define TRUE !FALSE #define TRUE !FALSE
@ -29,7 +31,7 @@ int main(int argc, char *argv[])
pid_t pid; pid_t pid;
int retval = 0; int retval = 0;
if (argc != 1){ if (argc != 2){
fprintf(stderr, "usage: %s\n", argv[0]); fprintf(stderr, "usage: %s\n", argv[0]);
return 1; return 1;
} }
@ -43,6 +45,14 @@ int main(int argc, char *argv[])
while (wait(&status) != pid); while (wait(&status) != pid);
retval = WEXITSTATUS(status); retval = WEXITSTATUS(status);
}else{ }else{
/* change profile so that ptrace can fail */
if (change_hat(argv[1], SD_ID_MAGIC + 1) == -1 &&
errno != EPERM) {
/* confined process failed to change_hat */
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
return errno;
}
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1){ if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1){
fprintf(stderr, "FAIL: ptrace failed - %s\n", fprintf(stderr, "FAIL: ptrace failed - %s\n",
strerror(errno)); strerror(errno));