Debugging session

Since a couple of days I am having issues compiling programs that is using the autotools generated ./configure script. This time I decided to record the steps along. Hopefully it will be useful to somebody else.

First symptoms

$ brew install e2fsprogs
[snip]
checking for additional special compiler flags... (none)
checking for grep that handles long lines and -e... ./configure: line 4465:
conftest.nl: Permission denied
configure: error: no acceptable grep could be found in
/usr/local/Library/ENV/4.3:/usr/local/opt/pkg-config/bin:/usr/local/opt/gettext/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/xpg4/bin

All compiles would fail on that same grep detection. And while OSX’s command-line tools are a bit clunky I never had that issue in the past.

I tried looking on Google and nobody has problems with conftest.nl specifically.

Case reduction

Why is conftest.nl not writeable ?

Run brew install e2fsprofs --debug and drop in the shell, edit ./configure. The file is a big pile of shell with thousands of tests. At line 4465 the script tries out the grep command on a file that was copied the line before.

Add ls -la 1>&2 in between and run ./configure again:

$ ./configure
[snip]
-rw-r--r--    1 zimbatm  wheel      20 Jul 24 11:18 conftest.in
-rw-r--r--    1 root     wheel      20 Jul 24 11:18 conftest.nl
[snip]

Why is the file owner root ?

After playing for a while I found the following case reduction:

$ touch test; /bin/cp test test2; ls -l test*
-rw-r--r--  1 zimbatm  staff  0 Jul 24 10:56 test
-rw-r--r--  1 root    staff 0 Jul 24 10:56 test2

Notice how it only happens with cp. touch, pipe redirection and other things work fine.

Is it umask ?

$ umask
022

Nope. Plus it would have affected the other tools as well.

Enter dtrace

dtruss is the equivalent of strace on Linux, that’s all I know about the dtrace ecosystem. It has to run as root so we have to do a little sudo dance.

$ touch test; sudo dtruss -f sudo -u $USER cp test test3
[snip]
 5894/0xa60e:  audit_session_self(0x7FFF5CB01A90, 0x7FFF5CB018C8, 0x4)     = 3587 0
 5894/0xa60e:  geteuid(0x7FFF5CB01A90, 0x7FFF5CB018C8, 0x0)    = 0 0
 5894/0xa60e:  getegid(0x7FFF5CB01A90, 0x7FFF5CB018C8, 0x0)    = 0 0
 5894/0xa60e:  getaudit_addr(0x7FFF5CB01B68, 0x30, 0x0)    = 0 0
 5894/0xa60e:  csops(0x1706, 0x7, 0x7FFF5CB01750)    = 0 0
 5894/0xa60e:  sigaction(0x1D, 0x7FFF5CB02528, 0x7FFF5CB02550)     = 0 0
 5894/0xa60e:  stat64("test2\0", 0x7FFF5CB02660, 0x1031001E0)    = -1 Err#2
 5894/0xa60e:  lstat64("test\0", 0x7FFF5CB025D0, 0xFFFFFFFFFFFFFFFF)     = 0 0
 5894/0xa60e:  umask(0x1FF, 0x7FFF5CB025D0, 0x0)     = 18 0
 5894/0xa60e:  umask(0x12, 0x7FFF5CB025D0, 0x0)    = 511 0
 5894/0xa60e:  stat64("test\0", 0x7FEDF8403910, 0x1)     = 0 0
 5894/0xa60e:  stat64("test2\0", 0x7FFF5CB02B88, 0xF86D0)    = -1 Err#2
 5894/0xa60e:  open("test\0", 0x0, 0x0)    = 3 0
 5894/0xa60e:  open("test2\0", 0x601, 0x81A4)    = 4 0
 5894/0xa60e:  fstatfs64(0x4, 0x7FFF5CB01C38, 0x0)     = 0 0
 5894/0xa60e:  fstat64(0x4, 0x7FFF5CB024B0, 0x0)     = 0 0
 5894/0xa60e:  fchmod(0x4, 0x8180, 0x0)    = 0 0
 5894/0xa60e:  read(0x3, "\0", 0x100000)     = 0 0
 5894/0xa60e:  fchmod(0x4, 0x81A4, 0x0)    = 0 0
 5894/0xa60e:  fstat64_extended(0x3, 0x7FEDF84039C8, 0x7FEDF8403B00)     = 0 0
 5894/0xa60e:  fstat64(0x4, 0x7FFF5CB01B10, 0xF8580)     = 0 0
 5894/0xa60e:  fchmod(0x4, 0x1A4, 0x0)     = 0 0
 5894/0xa60e:  __mac_syscall(0x7FFF946F7CD2, 0x52, 0x7FFF5CB01A90)     = -1 Err#93
 5894/0xa60e:  flistxattr(0x4, 0x0, 0x0)     = 0 0
 5894/0xa60e:  flistxattr(0x3, 0x0, 0x0)     = 0 0
 5894/0xa60e:  fchmod(0x4, 0x1A4, 0x0)     = 0 0
 5894/0xa60e:  close(0x3)    = 0 0
 5894/0xa60e:  close(0x4)    = 0 0
[snip]

After skimming nothing comes to my attention so I ask my colleague to run the same command on his computer (we checked that he didn’t had that weird behavior).

https://gist.github.com/hamchapman/952f6c662b12e5b4995b

The umask(), open() and fchmod() flags are the same. geteuid() and getegid() are different though. How come the user ID and group ID is zero ?

ls -l /bin/cp
-rwsr-sr-x  1 root  wheel  24848 Oct 31  2013 /bin/cp

Aha. Why does /bin/cp have a setuid flag ?

The setuid flag changes the program to run as root even when invoked by a normal user. That would explain the problem. And chmod -s /bin/cp fixes the problem.

Cleanup

Running find /usr/local -user root and find $HOME -user root finds some files. I still don’t know how /bin/cp got the flag. My tinfoil had says intrusion but my experience says that crappy install scripts do these kind of things.

Ok, back to work.