0

In my script I want to open a specific (device driver) file as FD 3. exec 3< works fine for this in regular cases.

However the device driver file is only readable as root, so I'm looking for a way to open the FD as root using sudo.

-> How can I open a file (descriptor) with sudo rights?

Unfortunately I have to keep the file open for the runtime of the script, so tricks like piping in or out do not work. Also I don't want to run the whole script under sudo rights.

If sudo + exec is not possible at all, an alternative solution is that I could call a program, in background like sudo tail -f -- but this poses another set of problems:

  • how to determine whether the program call was successful
  • how to get error messages if the call was not successful
  • how to "kill" the program at the end of execution.

EDIT: To clarify what I want to achieve:

  • open /dev/tpm0 which requires root permissions
  • execute my commands with user permissions
  • close /dev/tpm0

The reason behind this is that opening /dev/tpm0 blocks other commands from accessing the tpm which is critical in my situation.

Thanks for your help

PeterH
  • 11
  • 1
  • 1
    This would be easier to answer if you were to show us some code that demonstrates the problem you're trying to solve. – larsks Dec 18 '17 at 13:43
  • Ok what I want to achieve is: * open /dev/tpm0 which requires root rights * do whatever my script needs to do, with user rights * close /dev/tpm0 The reason behind this is that I have to block access to /dev/tpm0 while my script is running. /dev/tpm0 is a blocking character device. – PeterH Dec 18 '17 at 13:48
  • Why can you only open the fd as root? – 123 Dec 18 '17 at 14:36
  • The file is owned by user root and group root and has permissions 0600. Changing the permissions is probably the other option, but really not preferred. – PeterH Dec 18 '17 at 14:46

1 Answers1

0

Can you just do something like the following?

# open the file with root privileges for reading
exec 3< <(sudo cat /dev/tpm0)

# read three characters from open file descriptor
read -n3 somechars <&3

# read a line from the open file descriptor
read line <&3

# close the file descriptor
exec 3<&-

In order to detect a failed open, you could do something like this:

exec 3< <(sudo cat /dev/tpm0 || echo FAILEDCODE)

Then when you first read from fd 3, see if you get the FAILCODE. Or you could do something like this:

rm -f /tmp/itfailed
exec 3< <(sudo cat /dev/tpm0 || touch /tmp/itfailed)

Then check for /tmp/itfailed; if it exists, the sudo command failed.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks larsks, this looks quite close to what I need - thank you! Two problems remain -- entering the password for sudo does not work (but this can be circumvented in doing something else with sudo beforehand) and I don't know how to detect whether the opening succeeded or not. – PeterH Dec 18 '17 at 14:34
  • As you say, there are various ways of addressing the issue with `sudo` (including (a) permitting *this particular command* with no password, or maybe (b) acquiring credentials earlier in the script, etc). Detecting whether or not the open succeeded is a little trickier because we don't get a return code from the failed i/o redirection. I've added a couple of options. – larsks Dec 18 '17 at 14:41
  • An entirely different solution would be to run a separate process (as `root`) that opens `/dev/tpm0` and provides some API (e.g., over a unix socket) that allows your non-root script to access it in a controlled fashion. – larsks Dec 18 '17 at 14:42
  • Thanks again -- one last step: Unfortunately cat /dev/tpm0 immediately returns on success. I would need to use something like `tail -f` to keep it open - but if successfull this never returns. :/ – PeterH Dec 18 '17 at 14:44
  • ...and if you have the option of using something other than `bash`, you may be able to take advantage of [passing a file descriptor between a `root` process and a non-`root` process](https://stackoverflow.com/a/28005250/147356). – larsks Dec 18 '17 at 14:44