Search code examples
macosbsddtrace

Why can't I trace syscalls made by `/bin/echo`?


I was wondering what syscalls are made by echo (the command, not the shell built-in), so I decided to snoop it via dtrace. Specifically I used dtruss.

Consider that the following works (tracing all syscalls made by sed):

🍔 sudo dtruss /usr/local/bin/sed 's/a/e/' <<< 'cat'
SYSCALL(args)        = return
thread_selfid(0x0, 0x0, 0x0)         = 470642 0
# and many more…

But if I try the same with echo, I get the following:

🍔 sudo dtruss /bin/echo 'cat'
dtrace: failed to execute /bin/echo: unknown error

In fact: there are many commands with which I get this error. The commonality is that those commands were all in /bin or /usr/bin.

Brendan's blog suggests that it is possible to use dtruss on commands such as ls (his example is sudo dtruss ls -l hfsslower.d, where hfsslower.d is a normal text file). The blog post was written in 2011, concerning Mac OS X. But I am aware that OS X has had various security enhancements since then.

Could it be that I am bumping into OS X security of some sort? I am using OS X 10.12 Sierra.


Solution

  • I should've tried searching the error message.

    Looks like it is indeed System Integrity Protection.

    You can no longer attach DTrace to «restricted» processes on your Mac. And by «restricted» I mean every single built-in utility, daemon or application.

    My interpretation of the article is:

    • csrutil enable --without dtrace is not sufficient to attach DTrace to built-in executables
    • You need instead to do a full csrutil disable (this turns off SIP completely, which is overkill and creates a gap in your security, but seems to be the only solution)