3

If I su user from my home directory I am getting a permission denied for bash-completion, but if I su user from another directory there is no error.

Can't locate strict.pm:   lib/strict.pm: Permission denied at 
/usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.

Line 7 of the referenced file is use strict; ... included with every version of perl since at least the late 90s.

su user sources /etc/bash.bashrc and the user being su'd to .bashrc. Why would the calling user's location in the filesystem change this?

See my repo for more details, but I think I've gotten the necessary basics here.

Edit: More description of the setup.

I've added the following lines to /etc/bash.bashrc (which is where the error is happening):

if [[ $USER == 'testloginfiles' ]]; then
    echo "/etc/bash.bashrc (-: $-) ($(shopt login_shell))"
    printf '@INC: %s\n' $(perl -e 'print join ":", @INC')
fi

And this is the output if I am in my home directory:

$ pwd;su testloginfiles
/home/harleypig
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
Can't locate strict.pm:   lib/strict.pm: Permission denied at /usr/bin/vendor_perl/bash-complete line 7.
BEGIN failed--compilation aborted at /usr/bin/vendor_perl/bash-complete line 7.
/home/testloginfiles/.bashrc (-: himBH) (login_shell        off)
[testloginfiles@sweetums harleypig]$

If I am in another directory (e.g., /tmp) I get the following:

$ pwd ; su testloginfiles
/tmp
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: lib:/usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell            off)
[testloginfiles@sweetums tmp]$

There is a relative path as @pcronin suggests, but neither my home directory nor /tmp have a lib directory. Why is one causing an error and the other is not?

harleypig
  • 1,264
  • 8
  • 25
  • 2
    If you have the relative path `lib` in your PERL5LIB or PERLLIB, this may be attempting to load a file relative to your current directory. Relative paths in `@INC` are bad and this is why `.` is no longer in the default `@INC` since Perl 5.26. – Grinnz May 10 '19 at 15:28

2 Answers2

2
  1. In Perl, use strict tells perl to go find, load and import symbols from a file named strict.pm. It does this by searching the ordered list of directories in the @INC list. See this answer for more information on how that gets built. The error you are seeing indicates that before successfully finding a strict.pm, perl searched in a path that the executing user (likely testloginfiles) did not have access to.

  2. The contents of @INC can be affected by both the directory from which the script is run, as well as environment variables. In your case, since the problem manifests itself when the program is run from one directory but not another, it's likely that one (or more) of the entries in @INC is a relative path, such as lib (instead of something like /usr/share/perl5), or, that an environment variable that can affect perl's @INC list is different in the target user's environment.

  3. Running perl -E 'print join("\n", @INC)'; will produce a list of locations that it will search. Run that in your regular user's shell, and compare the results to what happens if you add it to testloginfiles' .bashrc file. The difference in output should explain the difference in behavior.

UPDATE

  1. With the new information you provided, we see there are no differences in @INC, which leaves us to understand how the two cases interpreted @INC differently. As you found in the su man page, su isn't changing the current directory, which means that relative paths won't affect the intepretation of @INC at all. But, su is changing the user, so it means that the su'd user is testing if /home/harleypig/lib/strict.pm exists. I'd bet that the su'd user does not have permissions to read into harleypig's home directory to see if that file exists, thus causing the error.
Community
  • 1
  • 1
pcronin
  • 1,043
  • 1
  • 12
  • 17
  • 2
    Point 4 is the answer as to why I was getting that error. When running `PERL5LIB=lib su testloginfiles` as root, in roots home directory, I get the same error. Thank you. – harleypig May 11 '19 at 21:32
2

I was not reading the su man page closely enough. The answer is in the first section:

For backward compatibility, su defaults to not change the current directory and to only set the environment variables HOME and SHELL (plus USER and LOGNAME if the target user is not root).

So, my existing environment, which included PERL5LIB=lib. was left in place. /etc/bash.bashrc is being executed with whatever environment I have in place. This seems a possible security risk.

In any case, the following resolved the issue, though it still doesn't explain why it was only giving an error from my home directory:

$ pwd ; PERL5LIB= su testloginfiles
/home/harleypig
Password: 
/etc/bash.bashrc (-: himBH) (login_shell        off)
@INC: /usr/lib/perl5/5.28/site_perl:/usr/share/perl5/site_perl:/usr/lib/perl5/5.28/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib/perl5/5.28/core_perl:/usr/share/perl5/core_perl
/home/testloginfiles/.bashrc (-: himBH) (login_shell            off)
[testloginfiles@sweetums harleypig]$
harleypig
  • 1,264
  • 8
  • 25
  • 1
    Yes, there is a definite security risk, but it's in your environment, not in `su`. Specifically, `PERL5LIB` should only include absolute paths. By putting a relative path there, you create the possibility for an attacker to compromise your account by getting you to execute Perl code when in a directory which has a malicious `lib/` subdirectory. – Dave Sherohman May 11 '19 at 08:53
  • I've updated my answer with what I think is causing the error message. – pcronin May 11 '19 at 14:43