Executing commands

Updated: May 06, 2022

Don't despair, further abuses are possible!

We can create a symlink that has a ! or | as the first character. We can take this to mean, “Execute the following command and return the standard output of the command as the file content” (in the case of !) or “When writing data to the file, pipe it through the following command” (in the case of |).

Or, with the creative use of shell escape sequences, you can have the filename in the symlink actually be the name of a command to execute; the standard output of that command is the filename that gets used as the actual value of the symlink:

# ln -s \"redirector\" spud
# ls -l spud
-r--r--r--  1 root  root   44 Aug 16 17:41 spud@ -> /dev/server1
# ls -l spud
-r--r--r--  1 root  root   44 Aug 16 17:41 spud@ -> /dev/server2
# ls -l spud
-r--r--r--  1 root  root   44 Aug 16 17:41 spud@ -> /dev/server3

In this manner, you could implement some load-sharing functionality all by using what appears to be a “normal” symlink (the double quote character in "redirector" is what's used to tell the c_link() code that this command's standard output should be used as the value of the symlink). Our little program, redirector, simply has a printf() that outputs different server names.

And the fun doesn't end there, because when you're processing your c_link() handler, you have access to all of the client's information—so you can make decisions based on who the client is, what node they are based on, etc.

You're limited purely by your imagination and what you can get away with at a code review.