1

I have a file with a secret and a generator application that reads it and generates something similar to a license.
There are users on that Linux machine who are allow to use that application.
Because that app read that secret file, these users must have read permission to that file.

Is there a way to remove the read permission from these users - just let the app read that file through that app only, when these users run it?

I want to give only ones who run that app the ability to read that file, and through that file only. Not just cat it and watch its content.

  • I saw a way solving it using
chmod 400 secret_file
chmod 110 generator
chmod u+s generator

This way users in the same group as generator can execute generator and can't read secret_file.
But because generator is with setuid then generator can read secret_file.
This is a nice solution, but I wanted to have the user's name in generator, and using that solution I always get the owner's name.
This is how I get the user's name from c/cpp application:

#include <pwd.h>

uid_t uid = geteuid(); struct passwd *pw = getpwuid(uid); std::string user_name = pw->pw_name;

Is there another way to solve this issue?
Can somehow apparmor help? (I couldn't understand)

A follow up question - is there way to make file executable only through a specific script? What I mean is that I don't want generator to be executed from a shell. I want it to be executed only from another script generator.sh which calls generator, because I do more stuff in generator.sh. I want user who runs bluntly generator to fail, and user who runs generator.sh to succeed.

hudac
  • 779
  • How are you looking up the user's name? What you want is perfectly possible. (Please update your question to include a working sample of your code.) – Chris Davies Dec 30 '20 at 22:03
  • @roaima I added the 'get user's name' code – hudac Dec 30 '20 at 22:07
  • 1
    You're looking at the effective userid, not the real userid. – Chris Davies Dec 30 '20 at 22:22
  • 1
    If you want to do this as a script, the usual secure approach is with sudo – Chris Davies Dec 30 '20 at 22:22
  • @roaima so you're saying I just should change to uid_t uid = getuid(); and that's it, + using the chmod 110 generator, chmod u+s generator, right? wow, that's nice. Regarding the script, is that related to the follow up question? I want to have "normal" users who run the app generator, but just through a script. – hudac Dec 30 '20 at 22:33
  • I don't understand what you mean by making a "file executable only through a specific script". Did you mean to ask about making a file accessible only through a specific script? If so, that's very straightforward indeed – Chris Davies Dec 30 '20 at 22:34
  • @roaima what I mean is that I don't want generator to be executed from a shell. I want it to be executed only from another script generator.sh which calls generator, because I do more stuff in generator.sh. I want user who runs bluntly generator to fail, and user who runs generator.sh to succeed. – hudac Dec 30 '20 at 22:36
  • 1
    Please put that into your question, remembering to make the question easy to read (i.e. no "edit" or "update" statements - make the question text flow readably) – Chris Davies Dec 30 '20 at 22:37
  • @hudac, enforcing running the program through a script is harder, since you can't have setuid scripts. But you could have a setuid wrapper that runs the script (and nothing else), and that script can then run the final binary. Or use sudo to run the script. You might have problems with the shell disliking being setuid, though, see https://unix.stackexchange.com/questions/74527/setuid-bit-seems-to-have-no-effect-on-bash and https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts – ilkkachu Dec 30 '20 at 22:40

1 Answers1

2

Use getuid() instead of geteuid().

From the execve() man page:

If the set-user-ID bit is set on the program file referred to by pathname, then the effective user ID of the calling process is changed to that of the owner of the program file.

The "real" user ID, which getuid() returns is unchanged, that is, it's the UID of the user starting the process.


The other thing:

I don't want generator to be executed from a shell. I want it to be executed only from another script generator.sh which calls generator, because I do more stuff in generator.sh.

is harder, since you can't have setuid scripts. But you could have a setuid wrapper that runs the script (and nothing else), and that script can then run the final binary. Or use sudo to run the script. You might have problems with the shell disliking being setuid, though, see Setuid bit seems to have no effect on bash and Allow setuid on shell scripts .

Also note that including the shell may bring more possible issues security-wise, and that with any setuid program, you should be careful to make sure the execution environment is clean. That includes environment variables and file descriptors, but possibly other inheritable features too. One reason to use sudo is that it at least tries to deal with this sort of issues.

Another, possibly better way would be to implement the privileged process as a network service instead, and have the users just run a simple dumb client program.

ilkkachu
  • 138,973