/* while waiting for kernel compilations from Debian (and while waiting for my kernel compilations to finish), I coded a single module, which acts as a workaround for one particular exploit I found in one user's homedirectory. Disclaimer: 1.) I don't guarantee, that it will protect you from other exploits (it won't). 2.) I guarantee, it won't break anything (actually it will break some occassional ptrace situations, but for simple gdb and stuff, this is ok). 3.) I don't guarantee it will work. It may freeze your machine. YMMV. 4.) I'm not a linux kernel module coder. If you'll come with something better, drop me a note. 5.) Against this exploit, simple chmod 700 /proc would suffice (since it wants to open /proc/self/exe). This is somehow cleaner. 6.) It should unload correctly, if it won't freeze your system (see point 3:). Anyways, as a simple workaround, it works. Compile with gcc -o ptrace_workaround.o -c ptrace_workaround.c -I/usr/src/linux/include (/usr/src/linux should compile preconfigured kernel headers, or include from kernel-headers package). */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include #include #include /* The list of system calls */ MODULE_LICENSE("GPL"); extern void *sys_call_table[]; /*sys_call_table is exported, so we can access it */ int (*orig_sys_ptrace)(long request, long pid, long addr, long data); #define is_dumpable(tsk) ((tsk)->task_dumpable && (tsk)->mm->dumpable) int hacked_sys_ptrace (long request, long pid, long addr, long data) { struct task_struct *child; lock_kernel(); read_lock(&tasklist_lock); child = find_task_by_pid(pid); if (child) get_task_struct(child); read_unlock(&tasklist_lock); if (!child) { unlock_kernel(); return -ESRCH; } if (request!=PTRACE_ATTACH) { mb(); if ((child->euid!=child->uid) || (child->egid==child->gid)) { unlock_kernel(); return -EPERM; } } unlock_kernel(); orig_sys_ptrace(request, pid, addr, data); } int init_module (void) /*module setup */ { orig_sys_ptrace = sys_call_table[SYS_ptrace]; sys_call_table[SYS_ptrace] = hacked_sys_ptrace; return 0; } void cleanup_module (void) /*module shutdown */ { sys_call_table[SYS_ptrace] = orig_sys_ptrace; /*set ptrace syscall to the origal one */ }