On Sun, 10 Oct 2010 11:35:02 -0700 (PDT), Roland McGrath <rol...@redhat.com> wrote: > > 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.
Neat. Although returning just UTRACE_SYSCALL_ABORT doesn't work. It just makes the process hang for me. I had to do: return (no == SYS_socket) ? UTRACE_SYSCALL_ABORT | UTRACE_RESUME : UTRACE_SYSCALL_RUN | UTRACE_RESUME; to make it work. You probably didn't mention that because it was obvious but honestly it wasn't that clear for me and didn't see it was mentioned in the documentation. > > 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'. Neat^2. I think documenting this is a good idea as well. Maybe I should start writing a patch for the documentation to make it easier for new-comers like me :) > 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. Thanks, appreciated. > > 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. One question about report_syscall_exit, I'm trying to change the errno to EPERM for aborted system calls but I think I'm doing it wrong: static u32 ubox_syscall_exit(u32 action, struct utrace_engine *engine, struct pt_regs *regs) { enum utrace_syscall_action decision; decision = utrace_syscall_action(action); switch (decision) { case UTRACE_SYSCALL_ABORT: syscall_set_return_value(current, regs, -EPERM, -1); /* fall through */ default: return UTRACE_RESUME; } } The decision argument is never set to UTRACE_SYSCALL_ABORT for me. It's always 0 aka UTRACE_SYSCALL_RUN. > > 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). I'll check out is_compat_task(), thanks. > > 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. Not perfect but WFM. > > 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. Looks like really nice example for me! I'm reading it now :) > > Thanks, > Roland > Thanks for answering, I really appreciate it. -- Regards, Ali Polatel
pgpRh83B0Q9Ul.pgp
Description: PGP signature