Skip to main content

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

9
  • Stéphane, I don't understand your use of "-" in the above examples. In my experience, exec("the-script", ["the-script", "its", "args"]) becomes exec("/the/interpreter", ["/the/interpreter", "the-script", "its", "args"]), with of course the possibility of an interpreter option. Commented Aug 3, 2016 at 4:28
  • @jrw32982, #! /bin/sh - is the "always use cmd -- something if you can't guarantee that something won't start with -" good practice adage here applied to /bin/sh (where - as the end-of-option marker is more portable than --) with something being the path/name of the script. If you don't use that for setuid scripts (on systems that support them but not with the /dev/fd/x method mentioned in the answer), then one can get a root shell by creating a symlink to your script called -i or -s for instance. Commented Aug 3, 2016 at 9:00
  • Thanks, Stéphane. I had missed the trailing single hyphen in your example shebang line. I had to hunt for where it's documented that a single hyphen is equivalent to a double hyphen pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html. Commented Aug 3, 2016 at 20:24
  • It's too easy to forget the trailing single/double hyphen in the shebang line for a setuid script; somehow the system should take care of it for you. Disallow setuid scripts altogether or somehow /bin/sh should disable its own option processing if it can detect that it's running setuid. I don't see how using /dev/fd/x by itself fixes that. You still need the single/double hyphen, I think. Commented Aug 3, 2016 at 20:26
  • @jrw32982, /dev/fd/x starts with /, not -. The primary goal is to remove the race condition between the two execve()s though (in between the execve("the-script") which elevates privileges and the subsequent execve("interpreter", "thescript") where interpreter opens thescript later (which may very well have been replaces with a symlink to something else in the meantime). Systems that implement suid scripts properly do a execve("interpreter", "/dev/fd/n") instead where n has been opened as part of the first execve(). Commented Aug 4, 2016 at 6:41