Non-root users unable to read perl scripts

Hi,

This is really bizarre, I’m hoping someone has a clever idea for me.

Basically: I have a fresh Rocky 9 install. I did a minimal install and added a handful of packages. I enabled one of the security profiles when installing, so SELinux is running. The system is headless now so all access is via ssh.

The system has a handful of users, one of which is able to use sudo and become root.

I’ve been setting up the system and had basically no problems (I used CentOS 6 and 7 and briefly 8 so am generally familiar with the RHEL way of doing stuff). No problems until I tried to ssh in and clone a git repo, as one of the normal (non-root) users; then I got this unusual error:

fatal: cannot copy '/usr/share/git-core/templates/hooks/fsmonitor-watchman.sample' to '/home/[user]/[directory]/.git/hooks/fsmonitor-watchman.sample': Operation not permitted

I checked some obvious things:

  • The user is able to enter /usr/share/git-core/templates/hooks/ and list all of the files in the directory; all files in the directory give read access to everyone (they’re all 0755)
  • The user is clearly able to read and write files in its own home directory
  • The user is able to view (using e.g. vim or cat) every file in that directory except that one
  • As root, the file is accessible normally

So it’s weird. Permissions/access on that file are not different than the other ones in that directory. For fun, as root, I copied the file to the user’s home directory, chown’ed it to the user, chmod 0666, and the user still can’t open it (e.g. if I try to cat the file, cat says “Operation not permitted”).

After some digging, I found out what’s different about the file: it’s a perl script. Specifically, it starts with

#!/usr/bin/perl

To summarize what I’ve found after some more digging:

  • Every user that isn’t root on this system exhibits the same behavior
  • If I have a file, for example, test.pl, with the contents
use warnings;
print("Hello\n");

… I can view, edit, create, and execute it as any user (by executing perl test.pl), no problem

  • Any user that is not root is not able to view, edit, or execute any file that starts with the perl shebang
  • If I make a copy of the offending git script, the copy has the same problems
  • If I delete the shebang line from that file, the problem magically goes away
  • If, as the user, I create a file that starts with the perl shebang, once I save the file I can not re-open, view, or execute it
  • Files with, for example, a bash shebang, give no problems. Only perl
  • As far as I can tell, SELinux is not involved. I don’t see any DENY messages in audit.log, audit2why doesn’t see anything amiss, and if I temporarily switch it to permissive, the behavior doesn’t change
  • Perl itself seems to work fine; as root I can do things and as non-root users I can write, edit, and execute perl scripts as long as they don’t start with the shebang
  • There’s no noise in any log files that I can see; nothing in the systemd journal, nothing in audit.log, nothing in /var/log/messages

I’ve spent at least half an hour searching the web for anything like this but don’t see anything useful. I’ve used Linux on and off for nearly 25 years now and though I wouldn’t claim to be an expert I hope that I haven’t missed anything stupidly obvious, though at this point if I did I’ll be happy to take my lumps and move on.

Any thoughts?

Thanks!

What security profile did you enable? Maybe it has some kind of restrictions. I installed perl and git-core on my system, and then copied that fsmonitor-watchman.sample to a standard user and ran it without problems. I did not choose a security profile during install, but I do have selinux enabled.

[root@rocky9 hooks]# cp fsmonitor-watchman.sample /home/ian/

and ran it:

[ian@rocky9 ~]$ ./fsmonitor-watchman.sample 
Use of uninitialized value $version in string ne at ./fsmonitor-watchman.sample line 25.
Use of uninitialized value $version in concatenation (.) or string at ./fsmonitor-watchman.sample line 26.
Unsupported query-fsmonitor hook version ''.
Falling back to scanning...

selinux:

[ian@rocky9 ~]$ getenforce
Enforcing

I also git cloned one of my own repos on github without any issues as well.

For just the perl part and the shebang, you could also try as standard user

/usr/bin/perl -v
/usr/bin/perl -e 'print "hello world\n";'

This will just execute directly.

Thanks for the response! I used the “[DRAFT] DISA STIG for Red Hat Enterprise Linux 9” profile, which is one of the stricter ones and I feel like it’s probably what’s relevant here. I did check audit.log and though it sees me try to execute perl scripts, it doesn’t seem to mind. However the security profile is more than just SELinux so there could be other elements of it. I’m going to try to look at that today.

One note is that the fsmonitor-watchman.sample script isn’t really the issue, it’s just apparently the first perl script I tried to access as a user on the system, by initializing a git repo. Generally, perl works fine on the system, even as a user:

elliott-a@corp:~$ echo 'print("Hello\n");' > test.pl
elliott-a@corp:~$ cat test.pl
print("Hello\n");
elliott-a@corp:~$ perl test.pl
Hello

… no problem. BUT:

elliott-a@corp:~$ (echo '#!/usr/bin/perl' ; echo 'print("Hello\n");') > test2.pl
elliott-a@corp:~$ cat test2.pl
cat: test2.pl: Operation not permitted
elliott-a@corp:~$ perl test2.pl
Can't open perl script "test2.pl": Operation not permitted
elliott-a@corp:~$ chmod +x test2.pl
elliott-a@corp:~$ ./test2.pl
-bash: ./test2.pl: Operation not permitted
elliott-a@corp:~$ cp test2.pl test3.pl
cp: cannot open 'test2.pl' for reading: Operation not permitted
elliott-a@corp:~$ rm test2.pl
elliott-a@corp:~$

So basically, having the shebang in the file (specifically perl - if it’s /usr/bin/bash, or /bin/sh, there’s no problem) prevents non-root users from reading the file. I poked at /etc/fapolicyd/rules.d a bit this morning and there are several rules that could be relevant, but none of seem to do what I’m seeing. E.g. there’s a 70-trusted-lang.rules file:

# Allow any program to open trusted language files

allow perm=open all : ftype=%languages trust=1
deny_audit perm=any all : ftype=%languages

… looks good to me? A few others like that. text/x-perl is a member of %languages.

I might try to set up a test system with a different security profile and see if the behavior changes. I’ve always used the DISA STIG profiles in the past, but they’re probably overkill for my actual use case. I’m probably going to poke more at fapolicy first, because I’d rather not go through re-installing if I don’t have to!

Thanks

UPDATE: It’s definitely fapolicyd. If I stop the fapolicyd service, the problem goes away. This afternoon I’ll start fiddling with that; I’ve gotta admit I’ve never really touched it so this will be new and exciting but it’s good to have a target now!

1 Like

OK, so apparently the fapolicy with this security profile is just absurdly strict. I added a rule to /etc/fapolicyd/rules.d:

root@corp:/etc/fapolicyd/rules.d# cat 65-perl.rules
# Allow all perl script execution and sourcing

allow perm=any all : ftype=text/x-perl

… and things seem to work now. phew

1 Like

A related chaper in docs

It implies that apps in the official repos are trusted, so defualt perl should be trusted.

I’d still be interested in the command lines above where it runs perl direct as opposed to in a script.

This was a useful page, yes. It is interesting that a) git, which was installed with the OS, didn’t work locally (presumably because that file wasn’t whitelisted), and b) I could basically run any perl script I wanted, as long as it didn’t start with shebang, which definitely limits the utility of whatever they were going for.