简体   繁体   中英

Perl modules not loading correctly when running as non-root user

I'm running into an issue with Perl on a linux system.

When installing new modules (as root), I would occasionally have issues where running scripts as a regular user, I would not be able to access the new module without manually going in and chmod 775'ing the module related files and directories.

I recently performed a CPAN upgrade, as well as installing several modules for a new project. Now, Perl has become almost unusable as a regular user, because of errors that don't appear to be permissions related.

For example, the following very simple script runs fine as root, but returns an error run as a regular user:

#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util;

As you can see, the script literally does nothing except attempt to load the Scalar::Util module. As a regular user, it returns this error:

**List::Util object version 1.21 does not match bootstrap parameter 1.42 at /usr/lib64/perl5/DynaLoader.pm line 223.
Compilation failed in require at /usr/local/lib64/perl5/Scalar/Util.pm line 22.
Compilation failed in require at ./scalar-test.pl line 4.
BEGIN failed--compilation aborted at ./scalar-test.pl line 4**

When I sudo cpan and try install List::Util , I get back: List::Util is up to date (1.42).

CLARIFICATION: This is happening with several modules, not just the one example. It does not appear to affect every module that was upgraded though; it's several though.

The fact that root can run the scripts says to me that either there is another, underlying permissions issue I'm not seeing, OR PERL is configured slightly different in some way for root than my regular account which is causing it not to find this module.

A search for the List.pm file is returning:

 » sudo find / -name List.pm 

/usr/share/perl5/I18N/LangTags/List.pm
/opt/OV/nonOV/perl/a/lib/5.8.8/I18N/LangTags/List.pm
/root/.cpan/build/perl-5.22.1-D0_eFO/dist/I18N-LangTags/lib/I18N/LangTags/List.pm

 » ls -l /usr/share/perl5/I18N/LangTags/List.pm
-rw-r--r-- 1 root root 28826 Nov  6  2014 /usr/share/perl5/I18N/LangTags/List.pm

 » ls -l /opt/OV/nonOV/perl/a/lib/5.8.8/I18N/LangTags/List.pm
-r--r--r-- 1 bin bin 28826 Nov 30  2012 /opt/OV/nonOV/perl/a/lib/5.8.8/I18N/LangTags/List.pm

 » sudo ls -l /root/.cpan/build/perl-5.22.1-D0_eFO/dist/I18N-LangTags/lib/I18N/LangTags/List.pm
-r--r--r-- 1 1018 513 28826 Oct 17 08:32 /root/.cpan/build/perl-5.22.1-D0_eFO/dist/I18N-LangTags/lib/I18N/LangTags/List.pm

System is RHEL 6.6 x64, Perl is v5.10.1


**» type perl**
perl is hashed (/usr/bin/perl)

**» which perl**
/usr/bin/perl 

**» sudo type perl**
sudo: type: command not found 

**» sudo which perl**
/usr/bin/perl

**» echo ${!PERL*}**
[Nothing Returned] 

**» sudo echo ${!PERL*}**
[Nothing Returned]

**» perl -wle 'print join("\n", @INC)'**
/usr/local/lib64/perl5 
/usr/local/share/perl5 
/usr/lib64/perl5/vendor_perl 
/usr/share/perl5/vendor_perl 
/usr/lib64/perl5 
/usr/share/perl5 
[run with sudo returns identical list]

[Edited for brevity] 
cpan[1]> o conf 
$CPAN::Config options from /usr/share/perl5/CPAN/Config.pm: 
build_dir [/root/.cpan/build] 
build_dir_reuse [0] 
build_requires_install_policy [ask/yes] 
connect_to_internet_ok [1] 
cpan_home [/root/.cpan] 
keep_source_where [/root/.cpan/sources] 
make [/usr/bin/make] 
make_install_make_command [/usr/bin/make] 
makepl_arg [INSTALLDIRS=site] 
prefer_installer [MB] 
prefs_dir [/root/.cpan/prefs] 

I redacted a few lines here from other user's folders

 » sudo find / -name Util.pm | grep "List/Util.pm"
/usr/lib64/perl5/List/Util.pm
/usr/local/lib64/perl5/List/Util.pm
/home/{USERNAME REDACTED}/.cpanm/work/1448660183.31550/ExtUtils-MakeMaker-7.10/bundled/Scalar-List-Utils/List/Util.pm
/root/.cpan/build/Scalar-List-Utils-1.42-2c3ONp/lib/List/Util.pm
/root/.cpan/build/Scalar-List-Utils-1.42-2c3ONp/blib/lib/List/Util.pm
/root/.cpan/build/Scalar-List-Utils-1.42-NOwU0A/lib/List/Util.pm
/root/.cpan/build/Scalar-List-Utils-1.42-NOwU0A/blib/lib/List/Util.pm
/root/.cpan/build/perl-5.22.1-D0_eFO/cpan/Scalar-List-Utils/lib/List/Util.pm

Per request of brian d foy, I installed a new module. This module Config::Onion was not previously installed, so nothing old to conflict. The module installs OK, but I created an onion-test.pl script, same as above, and it has the same issue where it only loads the module as root.

 » sudo perl -MConfig::Onion -e 'print "Module: " . $ARGV[0] . "\nVersion: " . $ARGV[0]->VERSION . "\n\n"' Config::Onion
Can't locate Config/Onion.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
BEGIN failed--compilation aborted.

 » sudo cpan
Terminal does not support AddHistory.

cpan shell -- CPAN exploration and modules installation (v2.10)
Enter 'h' for help.

cpan[1]> install Config::Onion

[Redacted for brevity. No errors noted during this process.]

Result: PASS
  DSHEROH/Config-Onion-1.004.tar.gz
  /usr/bin/make test -- OK
Running make install
Prepending /root/.cpan/build/Config-Onion-1.004-TigyuT/blib/arch /root/.cpan/build/Config-Onion-1.004-TigyuT/blib/lib to PERL5LIB for 'install'
Manifying 2 pod documents
Installing /usr/local/share/perl5/Config/Onion.pm
Installing /usr/local/share/perl5/Config/Onion/Simple.pm
Installing /usr/local/share/man/man3/Config::Onion.3pm
Installing /usr/local/share/man/man3/Config::Onion::Simple.3pm
Appending installation info to /usr/lib64/perl5/perllocal.pod
  DSHEROH/Config-Onion-1.004.tar.gz
  /usr/bin/make install  -- OK

 » cd /usr/local/share/perl5/Config
 » sudo ls -l  Onion
total 4
-r--r--r-- 1 root root 1856 May  9  2014 Simple.pm

 » sudo find / -name Onion.pm
/usr/local/share/perl5/Config/Onion.pm
/root/.cpan/build/Config-Onion-1.004-TigyuT/lib/Config/Onion.pm
/root/.cpan/build/Config-Onion-1.004-TigyuT/blib/lib/Config/Onion.pm


onion-test.pl:

#!/usr/bin/perl
use strict;
use warnings;

use Config::Onion;



 » ./onion-test.pl
Can't locate Hash/Merge/Simple.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/share/perl5/Config/Onion.pm line 9.
BEGIN failed--compilation aborted at /usr/local/share/perl5/Config/Onion.pm line 9.
Compilation failed in require at ./onion-test.pl line 29.
BEGIN failed--compilation aborted at ./onion-test.pl line 29.


 » sudo ./onion-test.pl
[No Errors]

Per Ikegami, I ran this command:

sudo chmod -R go+rX                   \
   /usr/local/lib64/perl5        \
   /usr/local/share/perl5        \
   /usr/lib64/perl5/vendor_perl  \
   /usr/share/perl5/vendor_perl  \
   /usr/lib64/perl5              \
   /usr/share/perl5 

Both of my test scripts, with Scalar::Util and Config::Onion are loading the modules without error. I think his solution is the right one for the issue I was having, and I've marked it accordingly. Thanks everyone for your research, and to Ikegami for hitting on the solution.

List/Util/Util.so probably exists twice in

/usr/local/lib64/perl5 
/usr/local/share/perl5 
/usr/lib64/perl5/vendor_perl 
/usr/share/perl5/vendor_perl 
/usr/lib64/perl5 
/usr/share/perl5 

They are different versions. The newer one can only be accessed by root. If this is the problem it will be solved using

chmod -R go+rX                   \
   /usr/local/lib64/perl5        \
   /usr/local/share/perl5        \
   /usr/lib64/perl5/vendor_perl  \
   /usr/share/perl5/vendor_perl  \
   /usr/lib64/perl5              \
   /usr/share/perl5 

I can only get so far on the information you provide, but here's a start. If you fill in some details we may be able to figure out this problem.

These sorts of error typically mean that you have two versions of the same module installed in different places or that the it was upgraded incompletely in one place (perhaps because someone tried it by hand, had insufficient permissions, or was interrupted). The program is able to load one part of the module from one source, fails to load a second part and looks elsewhere. Hence you get the mismatch.

In your case, it looks like you have List::Util in both /usr/lib64/perl5 and /usr/local/lib64/perl5 . From your @INC , you look in /usr/local/lib64/perl5 first. I'm guessing that's where the newest version should be. For some reason, it doesn't load right so it keeps looking and finds the old version in /usr/lib64/perl5 , but that's a mismatch.

For pure Perl files, these matches don't usually matter. However, for the compiled (XS) modules, the details of their compilation have to match up. Different versions of the same compilation tools, or different inputs to the same versions, likely cause incompatible formats. Or, different versions of the same Perl module name might have been reorganized so they don't match up with the binary component of previous versions. Hence the error message you get after something else already went wrong.

I wonder in your case if you've set an odd umask so that your root module installation doesn't make the file readable (or the directory executable) so other users can see the files. What were the permissions before you changed them? You should track down that problem since you said you've had the same problem previously (and may again).

The cpan module can find it for you looking through the current Perl's @INC . I haven't upgraded List::Util on this version of Perl, and it's found under lib/5.22.0/darwin-2level :

$ cpan -D List::Util
CPAN: Storable loaded ok (v2.53)
Reading '/Users/brian/.cpan/Metadata'
  Database was generated on Tue, 26 Jan 2016 12:17:02 GMT
List::Util
-------------------------------------------------------------------------
    List utilities (eg min, max, reduce)
    P/PE/PEVANS/Scalar-List-Utils-1.42.tar.gz
    /usr/local/perls/perl-5.22.0/lib/5.22.0/darwin-2level/List/Util.pm
    Installed: 1.41
    CPAN:      1.42  Not up to date
    Graham Barr (GBARR)
    gbarr@pobox.com

After I update it, the update is in lib/site_perl/5.22.0/darwin-2level , a different directory. CPAN.pm does not remove old versions, it merely shadows them. I still have the version that originally came with your Perl, and now you have an update in site_perl

$ cpan -D List::Util
CPAN: Storable loaded ok (v2.53)
Reading '/Users/brian/.cpan/Metadata'
  Database was generated on Tue, 26 Jan 2016 12:17:02 GMT
List::Util
-------------------------------------------------------------------------
    CPAN: Module::CoreList loaded ok (v5.20150520)
List utilities (eg min, max, reduce)
    P/PE/PEVANS/Scalar-List-Utils-1.42.tar.gz
    /usr/local/perls/perl-5.22.0/lib/site_perl/5.22.0/darwin-2level/List/Util.pm
    Installed: 1.42
    CPAN:      1.42  up to date
    Graham Barr (GBARR)
    gbarr@pobox.com

The paths may vary from system to system, but the idea is the same. I have different versions in different directories.

Now to recreate the problem. Curiously, in Perl v5.22, when I move the newly installed directory so it doesn't have the right name (forcing Perl to look in the wrong directory), I get a much friendly (although similarly unhelpful) message:

$ perl5.22.0 -MScalar::Util -e 1
List::Util version 1.42 required--this is only version 1.41 at /usr/local/perls/perl-5.22.0/lib/site_perl/5.22.0/darwin-2level/Scalar/Util.pm line 23.
Compilation failed in require.
BEGIN failed--compilation aborted.

It looks like you are using Perl 5.8.8. When I tried this same process on my system, cpan wrote files to the same location.

However, you can configure cpan for the installation locations. Your system may have helpfully done that for you. If you have the build logs (or cpan config or package manager info) to show us where it installed the new List::Util , that could help. Or, find us the list of List/Util.pm files you have installed and we could work backward. If you installed from a package, that might have chosen another location.

My advice is normally to leave the base installation alone and install everything into a different set of directories. If you are playing with the system perl (and it looks like you are), messing up the same perl that system needs for its admin and housekeeping tasks can cause additional headaches.

For those, who struggle with this kind of issue, and are running grsec linux kernel, check dmesg -T for occurences of messages, such as

[Thu Jul 13 12:39:32 2017] grsec: From 12.34.56.78: denied untrusted exec (due to file in group-writable directory) of /usr/local/lib/x86_64-linux-gnu/perl/5.24.1/auto/DBD/mysql/mysql.so by /usr/bin/perl[perl:9515] uid/euid:1000/1000 gid/egid:1000/1000, parent /bin/bash[bash:31545] uid/euid:1000/1000 gid/egid:1000/1000

This means non-root user was not able to use perl shared library mysql.so because of permissions on parent folder.

Solution good enough is to (for example, in this particular case) chmod parent folder gw (group -write)

chmod g-w /usr/local/lib/x86_64-linux-gnu/perl/5.24.1/auto/DBD/mysql/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM