> 1. From what I've read in the DocBook pages I've figured out that I have > to have two report entries. One for syscall_entry and one for > syscall_exit. On syscall_entry I should use syscall_get_nr() and check > if this number is equal to __NR_socket and return UTRACE_SYSCALL_ABORT > in that case and on syscall_exit, I need to call syscall_rollback() to > rollback the registers if utrace_syscall_action(action) returns > UTRACE_SYSCALL_ABORT. Is this correct?
The report_syscall_entry hook is the only one you need to prevent the system call from running. If it returns UTRACE_SYSCALL_ABORT, then the system call will fail with the ENOSYS error code. You only need to use a report_syscall_exit hook if you want the registers the user process sees after attempting the system call to be different from that. > 2. First I've read the documentation from Roland's page and figured out > it's out of date. report_syscall_entry callback used to have a struct > task_struct argument but now it doesn't. How should I get a "struct > task_struct" to pass to syscall_get_nr? Am I supposed to keep a > reference to the "struct pid" I used in init_module() and use > pid_task(pid, PIDTYPE_PID) or should I use find_get_pid() just as I used > in the init_module()? Those callbacks are made in the affected thread itself. So you can just use the magic variable 'current'. I've updated the web copy of the documentation. If you install the kernel-doc rpm on a Fedora system, that contains the version of this same documentation that goes with the kernel you have. > 3. In the report_syscall_exit callback, is the "struct pt_regs" argument > there so that the user can directly pass it to syscall_rollback() or do > I have to save the registers I had in report_syscall_entry() callback > and use them instead? You can just pass that pointer directly. In fact, the same pointer to 'struct pt_regs' will be passed to both callbacks. This is always the same pointer that 'task_pt_regs(current)' would return, just made quicker to access by having the argument to the callbacks. > 4. __NR_socket is available on some architectures and it's implemented > on top of __NR_socketcall on others. I'm running this example on x86_64. > How should my module figure out which mode the target process is running > in? I suppose this is related to the CS register. There are several ways to go about this, depending on how arch-specific you want to make it. On x86-64 it's possible for 32-bit processes to make 64-bit system calls and vice versa, though normal user programs will never actually do this. Perhaps the easiest and cleanest way, that both covers this arcane possibility and also works on other architectures, is to call is_compat_task() (under #ifdef CONFIG_COMPAT). > Having figured that how am I supposed to include system call numbers from > both architectures and use __NR_socketcall for 32bit mode and __NR_socket > for 64bit? Unfortunately, there is no clean way to refer to the 32-bit syscall numbers in code inside the 64-bit kernel. socketcall is not one of the few listed in asm/ia32_unistd.h, so off hand I think you'd just have to hard-code the i386 __NR_socketcall value in your module. > 5. Is there any project in the outer-space that does something like > this, sandboxing or monitoring system calls, from which I can learn > more? Renzo Davoli's umview/kmview is just such an animal. See http://wiki.virtualsquare.org for details. Thanks, Roland