I am writing a regular compiled application that needs to create a special file and write a magic cookie into it. I can’t write the file directly from the application, the system security model requires me to launch a helper tool with elevated privileges to do the trick. I can supply any number of arguments to the helper tool. Now I would like to pick some very simple system command that would serve as the helper tool and create the file for me. Something like this:

/bin/sh -c "/bin/echo -n 'magic' > /some/where/file"

Simple touch does not cut it as I need to write the cookie into the file, a simple echo without the shell wrapper does not work as it needs redirection to write the file. I don’t feel comfortable calling the shell with root privileges to do such a trivial task. Is there some really simple, constrained system command that I could call to write the file for me?

  • Is there a reason why /bin/sh -c 'echo magic > /path/to/magic/file' does not work? That would be an executable file and two arguments. You would need to build the last argument as a string (with sprintf or equivalent). Is there as reason this wouldn't work for you? From your question it sounds like doCommandAsRoot() does not take input to stream to the command, correct? Otherwise you could replace the last argument with 'cat > /path/to/magic/file' and pass the data instead of constructing a string. – Arcege Feb 22 '11 at 16:56
  • The shell example works, but I’d hate to call the shell with root privileges just to create a simple file. The library does take a communication pipe argument (it’s AuthorizationExecuteWithPrivileges), that could be used to write the cookie using tee. Thanks! – zoul Feb 22 '11 at 17:05
  • See also stackoverflow.com/a/18146890/2032064 – Mifeet Oct 28 '16 at 16:47

How about this:

echo -n 'magic' | sudo tee /some/where/file > /dev/null

Sure there are redirections in this but only tee runs as root not a shell. Works with dd of=... too.

  • 2
    Sorry, I obviously have trouble explaining myself lately. The problem is that when I want to run something with the elevated privileges, I have to go through a special library call (something like doCommandAsRoot). And this function only accepts a path to the command and its arguments, so there’s no way for me to use output redirection right away. I could go through shell (as shown in the question), but I don’t like that security-wise. – zoul Feb 22 '11 at 16:10
  • @zoul: I thought you are writing a shell script. Is it OK to write the magic cookie to a file that is accessible for unprivileged processes? If it is then write it to such a file and call doCommandAsRoot("dd", "if=/tmp/unprotected_file", "of=/some/where/file"). – stribika Feb 22 '11 at 16:28
  • No, it’s a regular compiled application (question updated). I’m just looking for “shell” commands to serve as the helper so that I don’t have to write it myself. Yes, the cookie is nothing sensitive. The dd example is pretty close to what I want, thank you. Could you think of something even simpler? – zoul Feb 22 '11 at 16:38
  • Sure — you could use cp or mv instead of dd. – mattdm Feb 22 '11 at 16:51
  • I mean simpler as without the need to copy :) – zoul Feb 22 '11 at 16:54

Without output redirect, without pipe, but with "here string":

dd of=/some/where/file <<<'magic'
  • One downside of this approach is dd writes some stats to stdout. You can use > /dev/null to hide them, but at that point you might as well use tee. – studgeek Aug 1 '18 at 20:18
  • 1
    This worked for me in an unusual situation where I could not use output redirection or pipes. status=none will suppress all other output from modern versions of GNU coreutils dd. – Michael Hampton Nov 19 at 21:21

There's another consideration, which is that you don't want to put the value of the magic cookie on a command line, since that can be observed by other users. Even if the program is short-lived (including if the program zeros out the command line string), there is the opportunity for attack. So, a theoretical:

writestringtofile 'magic' /some/where/file

is a dangerous approach. Therefore, I endorse @stribika's suggestion: write the value to a temporary file and copy it into place. Make sure to use a secure function to create the temporary file (mkstemp()) so that there's not a race condition there as well.

  • Thank you, this is a useful discussion. Fortunately the “magic cookie” is not a security device, it can be plainly seen by anybody. – zoul Feb 22 '11 at 18:39

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.