6

Please excuse me if this is too basic and you're tempted to throw an RTFM at me. I want to prevent users from copying certain files while granting them read access to the same files. I thought this was impossible until I came across this example in the SELinux Wiki:

 allow firefox_t user_home_t : file { read write };

So I was thinking, is it possible to give the files in question a mode of 0700 for instance, and use SELinux to grant read access only to the application that the users will normally be using to read the files?

Again, I'm sorry if this is too basic, it's just that I'm on a tight schedule and I want to give an answer to my boss one way or the other (if it's possible or not) as soon as possible and I know nothing about SELinux so I'm afraid reading on my own to determine whether it's possible or not would take me too much time. Please note that I'm not averse to reading per se and would hugely appreciate pointers to the relevant documentation if it exists.

So basically, my question is, is there a way to do this in SELinux or am I wasting my time pursuing such an alternative?

P.S. I'm aware that granting read access can allow users who are really intent on copying the files to copy and paste them from within the application they'll read them with; I'm just looking for a first line of defense.


EDIT

To better explain my use case:

  • The files in question are a mixture of text and binaries.
  • They need to be read by proprietary commercial software: they are simulation models for an electronics simulation software.
  • These models are themselves proprietary and we don't want the users simulating with them leaking them out for unauthorized use.
  • The software only needs to read the models and run a few scripts from these files; it will not write their contents anywhere.
  • In short, I want only the simulation software to have read and execute access to these files while preventing read access for the users.
2
  • Not really an SELinux expert, but if I can read the file but not copy it, would cat file | ssh otherserver 'cat > stolenfile' still work? Are you using rbash or some sort of restricted environment?
    – zje
    Mar 26, 2013 at 15:30
  • Haven't heard of rbash before. Seems interesting, but it's too restrictive for my requirements, unfortunately. I know that you can cat the file if you can read it. That's exactly my point. I want to disable all read access to the files so they can't be copied. From my skimming about SELinux, I came away with the impression that it aims to separate the users from the applications they're using; so I was wondering if I can enable read permissions only for the application that needs them. So the users can still use that application without having direct read permission to the files.
    – Joseph R.
    Mar 26, 2013 at 15:51

2 Answers 2

3

I think it's important to note that the cat isn't the problem in my comment above, but shell redirection. Are you trying to restrict copying of binaries or text files? If it's binaries, then I believe you can work something out with rbash (see http://blog.bodhizazen.net/linux/how-to-restrict-access-with-rbash/).

However, if it's text files, I'm not sure how you can prevent someone from just copying from their local terminal.

I'm not sure any general SELinux solution would be helpful here. Does your application that reads files need to write data anywhere? If not and these files only need to be read by your application, you could just give your application's type read-only access to the files of the type you would like it to read and don't give it write anywhere.

I think some more information on the exact permissions required by your use-case might be helpful, sorry for the vague answer.


UPDATE - MORE SPECIFIC ANSWER

I think you can achieve what you want without SELinux, as this is how many things are handled (e.g. normal users changing their password in /etc/shadow via the passwd command):

  • Make a separate user and/or group for your commercial software (might already be done)
  • Give the files read-only access by said user and/or group
  • Make sure normal users do not have access to those files
  • Make your executable setuid or getgid (depending on whether you used a group or user) e.g. chmod g+s or chmod u+s
  • When users run the application, they will now have the same permissions that the application user or group has, thereby allowing read access to those specific files within the desired application.

UPDATE2 - MULTIPLE USERS AND GROUPS If you have multiple applications and groups, you can likely achieve the functionality you are looking for with sudo. Many people are aware of its ability to let you run commands a root, but it's usefulness goes far beyond that example. I'm not sure this an ideal setup, but it's one way to do what you're attempting.

You can still make all the application files owned by the application, but then you can make separate groups for each set of files. This is what your /etc/sudoers or a file in /etc/sudoers.d/ could look like:

User_Alias    FILEGROUP1 = user1, user2
User_Alias    FILEGROUP2 = user3, user4
Cmnd_Alias    MYEDITOR = /usr/local/bin/myeditor, /usr/local/bin/mycompiler

FILEGROUP1    ALL=(:fileset1) NOPASSWD: MYEDITOR 
FILEGROUP2    ALL=(:fileset2) NOPASSWD: MYEDITOR 

Where user1 and user2 need access to files owned by the group fileset1 and user3 and user4 need access to files owned by the group fileset2. You could also use groups instead of users.

The users could access their files through the editor by doing sudo -g fileset1 /usr/local/bin/myeditor or something similar.

It might help to create some wrapper scripts for the necessary sudo -g commands for your users, especially since it sounds like may be a graphical application.

More details:

http://www.garron.me/linux/visudo-command-sudoers-file-sudo-default-editor.html

https://serverfault.com/questions/166254/change-primary-group-with-sudo-u-g

http://linux.die.net/man/8/sudo

4
  • What you're saying sounds really promising and along the lines of what I was thinking. Question edited to reflect my use case better.
    – Joseph R.
    Mar 28, 2013 at 7:53
  • Of course! It's so simple I feel stupid. I'll try it and accept your answer if it works.
    – Joseph R.
    Mar 28, 2013 at 15:57
  • No worries, it's not easy to come up with all the possibilities on your own. That's why we have stackexchange :-) Let us know how it goes!
    – zje
    Mar 28, 2013 at 20:55
  • Haven't actually tried; probably will not as my use case got more complicated: there will be several sets of models and different groups of people should be allowed to use each set. Your answer was still informative and useful, though.
    – Joseph R.
    Mar 31, 2013 at 22:37
1

You can achieve this crabwise only. The problem is that there is no "copy()" syscall. Copying files is done by reading the source and writing/creating the target.

Thus your only chance is to limit access to those files to such applications which do not allow making copies. This can be a difficult assessment though as "don't make copies" is usually not an application's design target. Firefox obviously seems inappropriate for this.

But you could use a two-level solution:

  1. Restrict Firefox to write accesses in a certain directory (tree); this may become evil considering /tmp. So you may have to start Firefox with $TMP pointing to somewhere in its configuration directory.
  2. Prevent all other applications (which the user can access) from reading this directory. (From my AppArmor perspective) This boils down to forbidding the login processes access to these directories (for all users) and granting access to Firefox.

A more generic but indirect approach: Check which files are created and compare them to the forbidden ones. This is rather easy if the application has both files open simultaneously but this may be an unsafe assumption. Furthermore running everything through strace doesn't make a system faster, of course. And I don't know how FAM/fileschanged scales over a whole file system. This scaling problem (if it exists) may be "solved" by restricting all applications (except for a file manager) to write access in a single directory (and their config dir, of course) so that only this directory (and /tmp) needs to be scanned by FAM. You could log the read accesses to all protected files per process to speed up these checks. FAM can't do that but AppArmor audit can (so I guess SELinux can do that, too).

A really nice solution would be a FUSE module for the writable directory (in order to avoid race conditions) to do the checking.

1
  • Not really sure I understood all your of your answer. Some notes, though: I'm not focused on firefox as the target application: it just so happens that this is the example provided in the SELinux wiki FAQ. Also, your suggestions seem rather complicated for a first line of defense and from what I gather they limit performance as well. I think there should be a better way to do this via SELinux policy.
    – Joseph R.
    Mar 26, 2013 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .