14

From the find man page:

-exec command ;
    There are unavoidable security problems
    surrounding use of the -exec action; you should use the
    -execdir option instead.

-execdir command {} +
    Like -exec, but the specified command is run from the
    subdirectory containing the matched file, which is not
    normally the directory in which you started find.  This a much
    more secure method for invoking commands, as it avoids race
    conditions during resolution of the paths to the matched
    files.

What does this mean? Why are there race conditions with running it from the starting directory? And how are these security risks?

13

Found the details here:

The -exec action causes another program to be run. It passes to the program the name of the file which is being considered at the time. The invoked program will typically then perform some action on that file. Once again, there is a race condition which can be exploited here. We shall take as a specific example the command

 find /tmp -path /tmp/umsp/passwd -exec /bin/rm

In this simple example, we are identifying just one file to be deleted and invoking /bin/rm to delete it. A problem exists because there is a time gap between the point where find decides that it needs to process the -exec action and the point where the /bin/rm command actually issues the unlink() system call to delete the file from the filesystem. Within this time period, an attacker can rename the /tmp/umsp directory, replacing it with a symbolic link to /etc. There is no way for /bin/rm to determine that it is working on the same file that find had in mind. Once the symbolic link is in place, the attacker has persuaded find to cause the deletion of the /etc/passwd file, which is not the effect intended by the command which was actually invoked.

Not sure how likely anyone could ever exploit this; but I guess there's the answer!

  • In the above case, execdir would first chdir to /tmp/umsp before running the command, and so theoretically, an attacker's relinking the directory would have no effect.. if the relinking happened after find "decides" to evaluate -exec but before the rm command can do its work. But I wonder why this would make a difference: the attacker could simply do the relink after user has decided to write the find command. – Otheus Apr 3 '16 at 9:35
  • 1
    @RuiFRibeiro The link isn't the argument that's passed to the command, it's an intermediate directory. /tmp/umsp is a directory when find sees it, but when rm runs, the attacked has changed it to being a symbolic link to /etc. /tmp/umsp/passwd is a regular file all along, but not the same one. – Gilles Apr 3 '16 at 20:52
2

I believe that the reason why -exec is dangerous is because if the user would not specify the full name and path to the program to be executed, it would potentially execute the wrong program.

Example:

find /some/path -exec coolprogram

In /some/path, someone made another coolprogram, and it uploads all your data to some bad actor.

But wait, you say, don't you have to execute it as ./coolprogram? Yes, but some people have PATH=.:/bin:whatever, which will execute the program in the current directory.

This is probably simplified, but I think that it could be dangerous in some cases. I had to troubleshoot an issue once where a zero-byte cpio ended up in the wrong directory. It caused a program to crash because cpio did not work as it was running the zero-byte file in the directory.

  • 3
    These risks aren't isolated to find -exec. If you've put . in your path then simply executing coolprogram in your current dir is already dangerous, whether you use find to do it or not! – Danny Tuppeny Apr 3 '16 at 14:08
  • 1
    Agreed, but it seems that -execdir watches for the condition that I mentioned as well: The ‘-execdir’ action refuses to do anything if the current directory is included in the $PATH environment variable. This is necessary because ‘-execdir’ runs programs in the same directory in which it finds files – in general, such a directory might be writable by untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’ to appear in the name of the command to be run. – Doug Apr 3 '16 at 14:27
  • I guess the moral of the story is that having . in your path is a bad idea also, which is why I make sure it isn't in there. – Doug Apr 3 '16 at 14:31
  • Interesting to know about disallowing . in path and {} in the command. Maybe in future Linux will just forbid . in path entirely and tools won't need to implement their own safety checks! :) – Danny Tuppeny Apr 3 '16 at 14:34
  • 1
    I think 90% of the code I write is only to catch the 5% of things that go wrong. :) – Doug Apr 3 '16 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.