mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 16:35:02 +01:00
ptrace.patch
This commit is contained in:
parent
5b61f80b97
commit
93d88ebfd4
5 changed files with 55 additions and 44 deletions
|
@ -66,7 +66,7 @@ net_raw_net_raw=TRUE
|
|||
|
||||
# we completely disable ptrace(), but it's not clear if we should allow it
|
||||
# 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.
|
||||
syscall_reboot_args=off
|
||||
|
@ -75,9 +75,11 @@ syscall_setdomainname_args=dumb.example.com
|
|||
syscall_ioperm_args="0 0x3ff"
|
||||
syscall_iopl_args=3
|
||||
syscall_chroot_args=${tmpdir}
|
||||
syscall_ptrace_args=sub
|
||||
|
||||
# if a testcase requires extra subdomain rules, add them here
|
||||
syscall_chroot_extra_entries="/:r ${tmpdir}:r"
|
||||
syscall_ptrace_extra_entries="hat:sub"
|
||||
|
||||
testwrapper=changehat_wrapper
|
||||
|
||||
|
|
|
@ -7,15 +7,10 @@
|
|||
#include <sys/ptrace.h>
|
||||
#include <signal.h>
|
||||
#include <sys/user.h>
|
||||
#include <errno.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
|
||||
|
@ -28,17 +23,21 @@ int interp_status(int status)
|
|||
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == 0) {
|
||||
rc = RET_CHLD_SUCCESS;
|
||||
// rc = RET_CHLD_SUCCESS;
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = RET_CHLD_FAILURE;
|
||||
// rc = RET_CHLD_FAILURE;
|
||||
rc = -WEXITSTATUS(status);
|
||||
}
|
||||
} else {
|
||||
rc = RET_CHLD_SIGNAL;
|
||||
// rc = RET_CHLD_SIGNAL;
|
||||
rc = -ECONNABORTED; /* overload to mean child signal */
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* return 0 on success. Child failure -errorno, parent failure errno */
|
||||
int do_parent(pid_t pid, int trace, int num_syscall)
|
||||
{
|
||||
struct user regs;
|
||||
|
@ -48,13 +47,13 @@ int do_parent(pid_t pid, int trace, int num_syscall)
|
|||
rc = alarm(5);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "FAIL: unexpected alarm already set\n");
|
||||
return 0;
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (trace) {
|
||||
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_ATTACH) failed - ");
|
||||
return 0;
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if (ptrace(PTRACE_SYSCALL, pid, NULL, 0) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_SINGLESTEP) failed - ");
|
||||
return RET_FAILURE;
|
||||
return errno;
|
||||
}
|
||||
|
||||
while (wait(&status) != pid);
|
||||
|
@ -80,18 +79,19 @@ int do_parent(pid_t pid, int trace, int num_syscall)
|
|||
memset(®s, 0, sizeof(regs));
|
||||
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1) {
|
||||
perror("FAIL: parent ptrace(PTRACE_GETREGS) failed - ");
|
||||
return RET_FAILURE;
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
|
||||
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)
|
||||
{
|
||||
if (helper) {
|
||||
|
@ -104,13 +104,13 @@ int do_child(char *argv[], int child_trace, int helper)
|
|||
if (child_trace) {
|
||||
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1){
|
||||
perror("FAIL: child ptrace(PTRACE_TRACEME) failed - ");
|
||||
return RET_FAILURE;
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (raise(SIGSTOP) != 0){
|
||||
perror("FAIL: child SIGSTOP itself failed -");
|
||||
return RET_FAILURE;
|
||||
return errno;
|
||||
}
|
||||
/* 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 - ");
|
||||
|
||||
return RET_FAILURE;
|
||||
return errno;
|
||||
}
|
||||
|
||||
void sigalrm_handler(int sig) {
|
||||
|
@ -133,7 +133,8 @@ int main(int argc, char *argv[])
|
|||
int parent_trace = 1,
|
||||
use_helper = 0,
|
||||
num_syscall = NUM_CHLD_SYSCALLS,
|
||||
opt;
|
||||
opt,
|
||||
ret = 0;
|
||||
const char *usage = "usage: %s [-c] [-n #syscall] program [args ...]\n";
|
||||
char **args;
|
||||
|
||||
|
@ -170,27 +171,29 @@ int main(int argc, char *argv[])
|
|||
|
||||
pid = fork();
|
||||
if (pid > 0){ /*parent */
|
||||
int stat, ret;
|
||||
int stat;
|
||||
|
||||
ret = do_parent(pid, parent_trace, num_syscall);
|
||||
|
||||
kill(pid, SIGKILL);
|
||||
|
||||
if (ret < RET_CHLD_SUCCESS) {
|
||||
if (ret >= 0) {
|
||||
/* 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)) {
|
||||
if (ret > 0) {
|
||||
perror("FAIL: parent failed: ");
|
||||
} else if (ret == 0) { //||
|
||||
// (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 if (ret == -ECONNABORTED) {
|
||||
errno = -ret;
|
||||
perror("FAIL: child killed: ");
|
||||
} else {
|
||||
fprintf(stderr, "FAIL: child failed\n");
|
||||
errno = -ret;
|
||||
perror("FAIL: child failed: ");
|
||||
}
|
||||
} else if (pid == 0) { /* child */
|
||||
if (do_child(args, !parent_trace, use_helper))
|
||||
|
@ -200,5 +203,5 @@ int main(int argc, char *argv[])
|
|||
perror("FAIL: fork failed - ");
|
||||
}
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -28,10 +28,6 @@ bin=$pwd
|
|||
# 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
|
||||
|
||||
# Test Matrix:
|
||||
# 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
|
||||
|
||||
# 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
|
||||
genprofile image=ix$helper
|
||||
runchecktest "test 3b" pass -h -n 100 $helper
|
||||
runchecktest "test 4b" pass -h -n 100 -c $helper
|
||||
|
||||
genprofile $helper:ux
|
||||
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
|
||||
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: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
|
||||
genprofile image=$helper /bin/true:rix
|
||||
runchecktest "test 11" fail -h -n 2000 $helper /bin/true
|
||||
|
|
|
@ -28,12 +28,12 @@ bin=$pwd
|
|||
settest syscall_ptrace
|
||||
|
||||
# TEST A1
|
||||
runchecktest "PTRACE with no profile" pass
|
||||
runchecktest "PTRACE with no profile" pass sub
|
||||
|
||||
# TEST A2. ptrace will fail
|
||||
genprofile
|
||||
|
||||
runchecktest "PTRACE with confinement" fail
|
||||
runchecktest "PTRACE with confinement" fail sub
|
||||
|
||||
##
|
||||
## B. MKNOD
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "changehat.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
|
@ -29,7 +31,7 @@ int main(int argc, char *argv[])
|
|||
pid_t pid;
|
||||
int retval = 0;
|
||||
|
||||
if (argc != 1){
|
||||
if (argc != 2){
|
||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
@ -43,6 +45,14 @@ int main(int argc, char *argv[])
|
|||
while (wait(&status) != pid);
|
||||
retval = WEXITSTATUS(status);
|
||||
}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){
|
||||
fprintf(stderr, "FAIL: ptrace failed - %s\n",
|
||||
strerror(errno));
|
||||
|
|
Loading…
Add table
Reference in a new issue