Bug 1382706

Summary: LD_LIBRARY_PATH is missing in CGI scripts environment
Product: Red Hat Software Collections Reporter: Petr Pisar <ppisar>
Component: httpd24Assignee: Luboš Uhliarik <luhliari>
Status: CLOSED CANTFIX QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: httpd24CC: jorton, lkuprova
Target Milestone: beta   
Target Release: 2.4   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Known Issue
Doc Text:
When SELinux is enabled, the LD_LIBRARY_PATH environment variable is not passed through to CGI scripts invoked by httpd. As a consequence, it is impossible to invoke executables from Software Collections enabled in the /opt/rh/httpd24/service-environment file from CGI scripts run by httpd. To work around this problem, set LD_LIBRARY_PATH as desired from within the CGI script.
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-03-17 11:23:42 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Petr Pisar 2016-10-07 13:03:55 UTC
When fixing bug #1382514, I found out that CGI scripts started from httpd24-httpd-2.4.18-11.el7.x86_64 are missing LD_LIBRARY_PATH environment variable set when enabling a collection registered in /opt/rh/httpd24/service-environment.

Reproducer:

(1) Install httpd24-httpd and rh-perl524-perl.
(2) Register rh-perl524 collection in /opt/rh/httpd24/service-environment.
(4) Start httpd24-httpd service.
(3) Create this CGI script:

# cat /opt/rh/httpd24/root/var/www/cgi-bin/test 
#!/bin/sh
cat <<EOM
Content-Type: text/plain

EOM
set
perl -v

(4) Retrieve <http://localhost/cgi-bin/test> document.

Current behavior is the "set" command reports rh-perl524 executable paths in PATH, but it does not report LD_LIBRARY_PATH variable. As a result the "perl -v"  command from the CGI script fails and httpd error_log will contain:

[cgi:error] [pid 3807] [client ::1:49436] AH01215: perl: error while loading shared libraries: libperl.so.rh-perl524-5.24: cannot open shared object file: No such file or directory: /opt/rh/httpd24/root/var/www/cgi-bin/test

In my opinion, if httpd24-http support collections, it should pass LD_LIBRARY_PATH into CGI scripts. Otherwise it's not possible to use interpreters from registered collections. Actually it should pass any variable set when enabling a collection.

Comment 1 Petr Pisar 2016-10-07 13:23:40 UTC
I tried to put "PassEnv LD_LIBRARY_PATH" on various places, but without success. It will never show in the environment. While "SetEnv FOO BAR" written on next line in the httpd configuration works.

Comment 2 Petr Pisar 2016-10-10 10:57:12 UTC
It looks like the LD_LIBRARY_PATH is handled specially in mod_cgi. If I add these directives into /opt/rh/httpd24/root/etc/httpd/conf/httpd.conf to pass all variable set when enabling rh-perl524 (scl enable rh-perl524 '/usr/bin/env | grep rh-perl | sort'):

PassEnv LD_LIBRARY_PATH
PassEnv MANPATH
PassEnv PATH
PassEnv X_SCLS

Then all of them except LD_LIBRARY_PATH will be passed. I guess mod_cgi treats LD_LIBRARY_PATH specially. And all of that despite mod_env documentnation <http://httpd.apache.org/docs/current/mod/mod_env.html#passenv>.

Comment 3 Petr Pisar 2016-10-10 13:40:18 UTC
I suspect httpd to execute a CGI script via /sbin/suexec that is SUID, so ld-linux.so will ignore the LD_LIBRARY_PATH when linking /sbin/suexec. But in addition it will remove the variable from the environment, thus /sbin/suexec's child, the CGI script, will miss the LD_LIBRARY_PATH variable.

Comment 4 Petr Pisar 2016-10-10 15:12:26 UTC
If you could not find a proper fix, we would have to rebuild all collections to use RPATH in all of their ELF executable programs.

Comment 5 Joe Orton 2017-01-17 15:32:44 UTC
How were you enabling perl524 in service-environment, Petr? 

I can't reproduce this, vanilla httpd.conf.

[root@virt-el7sclY ~]# grep -v ^# /opt/rh/httpd24/service-environment 
HTTPD24_HTTPD_SCLS_ENABLED="httpd24 rh-perl524"
[root@virt-el7sclY ~]# rpm -q httpd24-httpd
httpd24-httpd-2.4.18-11.el7.x86_64
[root@virt-el7sclY ~]# rpm -V httpd24-httpd
[root@virt-el7sclY ~]# curl -s http://localhost/cgi-bin/ptest | grep LD_LI
LD_LIBRARY_PATH=/opt/rh/rh-perl524/root/usr/lib64:/opt/rh/httpd24/root/usr/lib64

The special case in httpd is to ensure specifically that LD_LIBRARY_PATH *is* passed through to CGI scripts as-is.

You're right the suexec case will fail to pass through LD_LIBRARY_PATH, though, but suexec is *not* used by default (and is relatively rare these days).  I know some people patch suexec to allow passing LD_LIBRARY_PATH... not sure what the right thing is there.

Comment 6 Petr Pisar 2017-01-17 16:36:17 UTC
I have the same versions as you and I have the very same line as you in the /opt/rh/httpd24/service-environment.

I purged all the SCL packages and the /opt directory, installed packages the script and the service-environment again, and I still can reproduce it. I will try it again in a different virtual machine.

Comment 7 Joe Orton 2017-01-17 16:56:52 UTC
Hmmm, weird.  Can you check whether LD_LIBRARY_PATH is set in one of the httpd child processes when httpd24-httpd is running via /proc/XXXX/environ?

Comment 8 Joe Orton 2017-01-17 17:02:48 UTC
Ah ha.  I had SELinux permissive mode on for httpd_t.  Without permissive mode, I can reproduce.

Comment 9 Joe Orton 2017-01-17 17:24:27 UTC
I believe this is a deliberate result of SELinux policy, which clears LD_LIBRARY_PATH across the domain transition when the CGI script is exec'd (setting the  "AT_SECURE" flag).

https://lists.fedoraproject.org/archives/list/selinux@lists.fedoraproject.org/message/EQABLLVU4CS5H6AT56D7D5SQAXIZFZBH/

I'm not totally sure this is an appropriate default for the httpd_t->httpd_sys_script_t transition *for the httpd24 SCL*, but we don't have separate SELinux policy for httpd in RHSCL to base-RHEL.

It's one line of policy to over-rule this, and this isn't something people are hitting frequently (I guess), just documenting it is an option.