codeblog code is freedom — patching my itch

July 1, 2010

reporting all execs

Filed under: Blogging,Debian,Ubuntu,Ubuntu-Server — kees @ 2:24 pm

I recently learned about the process event connector, and went looking for an example program that could report all the exec()s that happen on my system to help with debugging things like AC plug/unplug scripts, etc.

After cleaning it up and adding some features to do a simple best-effort cmdline reporting, I’ve now got a tool that will report every program run on a system:

$ sudo ./cn_proc 
sending proc connector: PROC_CN_MCAST_LISTEN... sent
Reading process events from proc connector.
Hit Ctrl-C to exit
event: exec 17514 17514: ls -AF --color=auto (unconfined)
event: exec 17516 17516: date +%H:%M (unconfined)
event: exec 17518 17518: whoami (unconfined)

Change the values show_event, show_seq, show_cpu, show_security_context to set the reporting defaults. Or, if someone is feeling bored, it would rock to add getopt support instead.

It seems strange to me that only CAP_NET_ADMIN is needed to get access to this information.

© 2010, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.
CC BY-SA 4.0


  1. Hi, on Jaunty with kernel 2.6.28-19 there was no PROC_EVENT_SID so i removed 263-269 and it compiled, and works :)

    Comment by GNA — July 1, 2010 @ 10:46 pm

  2. You rock Kees! I’ve wanted to have this tool for several years and now I finally have it available!!! Thanks a million for blogging about this.

    Comment by martin — July 1, 2010 @ 11:54 pm

  3. This sounds like a handy debugging tool, easily preferable to strace -ff on system daemons to find out what’s being executed in response to events.

    Is there a package where it could be added?

    Comment by Matt Zimmerman — July 2, 2010 @ 1:21 am

  4. “It seems strange to me that only CAP_NET_ADMIN is needed to get access to this information.”

    An unprivileged user could construct this information (albeit less efficiently) by polling procfs (simplest version: running ps(1) repeatedly), so I’m not really surprised…

    Comment by Simon McVittie — July 2, 2010 @ 2:03 am

  5. I think that is already possible with accounting.
    I’ve implemented such a thing once:
    But I agree that your version is more useable.

    Comment by Folkert van Heusden — July 2, 2010 @ 2:06 am

  6. Your version of cn_proc seems to get stuck here at the first recvfrom(). I’m using debian squeeze with linux-image-2.6.32-5-amd64 2.6.32-15 inside Xen. Any idea what’s wrong? (And yes, I did try running long-lived processes like top from another terminal but they did not seem to have any effect cn_proc).

    $ sudo strace -f -s4096 -x ./cn_proc

    arch_prctl(ARCH_SET_FS, 0x7fb5f61db700) = 0
    mprotect(0x7fb5f5cf7000, 16384, PROT_READ) = 0
    mprotect(0x7fb5f61fa000, 4096, PROT_READ) = 0
    munmap(0x7fb5f61dd000, 110124) = 0
    getuid() = 0
    socket(PF_NETLINK, SOCK_DGRAM, 11) = 3
    getpid() = 23119
    bind(3, {sa_family=AF_NETLINK, pid=23119, groups=00000001}, 12) = 0
    rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
    write(2, “sending proc connector: PROC_CN_MCAST_LISTEN… “, 48sending proc connector: PROC_CN_MCAST_LISTEN… ) = 48
    rt_sigaction(SIGINT, {0x400fb4, [INT], SA_RESTORER|SA_RESTART, 0x7fb5f59d21f0}, {SIG_DFL, [], 0}, 8) = 0
    sendto(3, “\x28\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x4f\x5a\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00”, 40, 0, NULL, 0) = 40
    write(2, “sent\n”, 5sent
    ) = 5
    write(2, “Reading process events from proc connector.\nHit Ctrl-C to exit\n”, 63Reading process events from proc connector.
    Hit Ctrl-C to exit
    ) = 63

    Comment by Timo Juhani Lindfors — July 2, 2010 @ 6:53 am

  7. @GNA: cool. I’ve updated the tool to make that an #ifdef now

    @Matt: It could probably get added to procps. I’ve sent email to upstream:

    @Timo: for this to work, the kernel needs CONFIG_PROC_EVENTS. Beyond that, I’m not sure.

    Comment by kees — July 2, 2010 @ 11:12 am

  8. kees, ok. I assumed this was a standard feature in Debian but indeed

    $ grep PROC_E /boot/config-2.6.32-*
    /boot/config-2.6.32-3-amd64:# CONFIG_ACPI_PROC_EVENT is not set
    /boot/config-2.6.32-5-amd64:# CONFIG_ACPI_PROC_EVENT is not set

    does not look very promising. If I take the custom kernel route I might just as well enable CONFIG_KPROBES, apt-get install systemtap and write a few lines to log all execve()s.

    Comment by Timo Juhani Lindfors — July 4, 2010 @ 11:57 pm

  9. Just discovered this post from a link to your site.

    Thought you might like to see some work we did at MIT using the proc_connector a little while back. We wanted to understand how people were using MIT’s public Ubuntu workstations, so we used the proc_connector to track execs and report executable names. I wrote a Pyrex module so I could access proc_connector events from Python (for the higher-level filtering and processing):

    Comment by Evan Broder — October 19, 2010 @ 4:12 pm

  10. @Evan Cool! What did you discover people were doing most of the time?

    Comment by kees — October 19, 2010 @ 4:32 pm

Powered by WordPress