From nobody@FreeBSD.org  Tue Jul 30 13:36:48 2002
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C9C1D37B400
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Jul 2002 13:36:48 -0700 (PDT)
Received: from www.freebsd.org (www.FreeBSD.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6E48943E31
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Jul 2002 13:36:48 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.4/8.12.4) with ESMTP id g6UKamOT051792
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 30 Jul 2002 13:36:48 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.4/8.12.4/Submit) id g6UKamu9051791;
	Tue, 30 Jul 2002 13:36:48 -0700 (PDT)
Message-Id: <200207302036.g6UKamu9051791@www.freebsd.org>
Date: Tue, 30 Jul 2002 13:36:48 -0700 (PDT)
From: Lee Brotherston <lee@nerds.org.uk>
To: freebsd-gnats-submit@FreeBSD.org
Subject: LD_LIBRARY_PATH security checks
X-Send-Pr-Version: www-1.0

>Number:         41179
>Category:       misc
>Synopsis:       [request] LD_LIBRARY_PATH security checks
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 30 13:40:01 PDT 2002
>Closed-Date:    Wed Nov 24 02:04:35 UTC 2010
>Last-Modified:  Wed Nov 24 02:04:35 UTC 2010
>Originator:     Lee Brotherston
>Release:        FreeBSD 4.6-RC #3
>Organization:
>Environment:
FreeBSD cybergimp.nerds.org.uk 4.6-RC FreeBSD 4.6-RC #3: Sat Jun 15 21:56:30 BST 2002 lee@cybergimp.nerds.org.uk:/usr/src/sys/compile/NEWGIMPYKERN  i386

>Description:
LD_LIBRARY_PATH does not perform suitable security checks (in my opinion)
when being used by the root user.  With this environment variable set root
will use alternative shared libraries which it will dynamically load, which
is the intended use (I believe).  However it does not perform the same
basic checks which would be applied when using ldconfig, that being (from
ldconfig(8)):

"For security reasons, directories which are world or group-writable
or which are not owned by root produce warning messages and are
skipped, unless the -i option is present."

A normal users LD_LIBRARY_PATH will be ignored if it is a setuid binary
that is being executed (again from ldconfig(8)):

"Special care must be taken when loading shared libraries into the
address space of set-user-Id programs.  Whenever such a program is
run, the dynamic linker will only load shared libraries from the hints
file.  In particular, the LD_LIBRARY_PATH is not used to search for
libraries."

So elsewhere in the OS the trend seems to be not to use this varible
where malicious code might be run with escalated privilages...

However you can use this variable as root, on a setuid binary (ok so
you're already root, just mentioning it :>), anywhere.. say /var/tmp,
which is owned by nobody and world writable!

The scope for inserting a malicious library is quite high there,
especially when you consider that when you su (from su(1)) "By default,
the environment is unmodified with the exception of USER, HOME, and
SHELL.", so you do not even need to get root to set this variable, but
some user in wheel that may later su.  If you want a full example I can
provide one, I'll just leave it out now to keep this short (yeah, that's
worked so far).
>How-To-Repeat:
It's probably easiest just to give this as an example:

$ export LD_LIBRARY_PATH="/var/tmp"
$ cp /usr/lib/libcrypt.so.2 /var/tmp/libcrypt.so.2
$ chmod 666 /var/tmp/libcrypt.so.2

(you can set pretty much any permissions, ownership, etc you want
depending on location)

$ su
Password:

# ldd /usr/bin/passwd
/usr/bin/passwd:
        libcrypt.so.2 => /var/tmp/libcrypt.so.2 (0x2806c000)
        librpcsvc.so.2 => /usr/lib/librpcsvc.so.2 (0x28085000)
        libutil.so.3 => /usr/lib/libutil.so.3 (0x2808d000)
        libc.so.4 => /usr/lib/libc.so.4 (0x28096000)

>Fix:
I don't have any patch code, but...

I would suggest that the same checks are applied when root uses
LD_LIBRARY_PATH as when ldconfig is used to generate hints files.  That
is  "directories which are world or group-writable or which are not
owned by root produce warning messages and are skipped", or perhaps a
simpler (although probably not as elegant) route might be to add
LD_LIBRARY_PATH to the list of environment variables which su modifies.
>Release-Note:
>Audit-Trail:

From: Ceri Davies <ceri@FreeBSD.org>
To: FreeBSD Gnats Submit <freebsd-gnats-submit@FreeBSD.org>
Cc:  
Subject: Re: misc/41179: LD_LIBRARY_PATH security checks
Date: Mon, 2 Jun 2003 15:15:44 +0100

 Adding to audit trail, from misfiled PR misc/52842:
 
 From: David Schultz <das@FreeBSD.ORG>
 Date: Sun, 1 Jun 2003 11:18:50 -0700
 Message-Id: <20030601181850.GA946@HAL9000.homeunix.com>
 References: <200207302036.g6UKamu9051791@www.freebsd.org>
 
  > # ldd /usr/bin/passwd
  > /usr/bin/passwd:
  >         libcrypt.so.2 => /var/tmp/libcrypt.so.2 (0x2806c000)
  >         librpcsvc.so.2 => /usr/lib/librpcsvc.so.2 (0x28085000)
  >         libutil.so.3 => /usr/lib/libutil.so.3 (0x2808d000)
  >         libc.so.4 => /usr/lib/libc.so.4 (0x28096000)
  
  The passage you quote in the manual applies to ldconfig(8), not to
  LD_LIBRARY_PATH.  There are no such checks for LD_LIBRARY_PATH for
  root or otherwise.  ldconfig(8) makes the checks as documented.
  
  Your proposal would add a large amount of overhead to program
  execution time, and to what end?  If someone with root privileges
  adds an untrusted directory to his LD_LIBRARY_PATH for some odd
  reason, how are we to stop him?  It isn't as clear cut as saying
  that a directory owned by root that isn't world-writable is
  trusted and other directories are untrusted.
  
  > A normal users LD_LIBRARY_PATH will be ignored if it is a setuid
  > binary that is being executed (again from ldconfig(8)):
  > 
  > "Special care must be taken when loading shared libraries into the
  > address space of set-user-Id programs.  Whenever such a program is
  > run, the dynamic linker will only load shared libraries from the hints
  > file.  In particular, the LD_LIBRARY_PATH is not used to search for
  > libraries."
  > 
  > So elsewhere in the OS the trend seems to be not to use this
  > varible where malicious code might be run with escalated
  > privilages...
  > 
  > However you can use this variable as root, on a setuid binary
  > (ok so you're already root, just mentioning it :>),
  > anywhere.. say /var/tmp, which is owned by nobody and world
  > writable!
  
  The rationale here is that a malicious user shouldn't be able to
  link a setuid binary against a trojanned library by manipulating
  LD_LIBRARY_PATH, thereby gaining the privileges of the owner of
  the binary, possibly root.  The root user is implicitly trusted
  and has the privileges of all the other users anyway, so you're
  ...um...preventing root from breaking root.
  
  > The scope for inserting a malicious library is quite high there,
  > especially when you consider that when you su (from su(1)) "By
  > default, the environment is unmodified with the exception of
  > USER, HOME, and SHELL.", so you do not even need to get root to
  > set this variable, but some user in wheel that may later su.  If
  > you want a full example I can provide one, I'll just leave it
  > out now to keep this short (yeah, that's worked so far).
  
  If you su to root from the account of an untrusted user, you're
  asking for trouble anyway.  There are many documented cases of
  people breaking root this way, and you don't even need to fiddle
  with LD_LIBRARY_PATH.  The untrusted user just sets his PATH to
  include a fake version of su(1) that records root's password,
  prints ``Sorry'', and spawns the real su(1).  The correct thing to
  do is to use su(1) only from trusted accounts.
 

From: Ceri Davies <ceri@FreeBSD.org>
To: FreeBSD Gnats Submit <freebsd-gnats-submit@FreeBSD.org>
Cc:  
Subject: Re: misc/41179: LD_LIBRARY_PATH security checks
Date: Mon, 2 Jun 2003 23:59:56 +0100

 Adding to audit trail, from misfiled PR misc/52869:
 
 From: Lee Brotherston <lee@nerds.org.uk>
 Date: Mon, 2 Jun 2003 17:16:07 +0100
 Message-Id: <20030602161606.GA26694@nerds.org.uk>
 References: <200207302036.g6UKamu9051791@www.freebsd.org> <20030601181850.GA946@HAL9000.homeunix.com>
 
  On Sun, Jun 01, 2003 at 11:18:50AM -0700, David Schultz wrote:
  > The passage you quote in the manual applies to ldconfig(8), not to
  > LD_LIBRARY_PATH.  There are no such checks for LD_LIBRARY_PATH for
  > root or otherwise.  ldconfig(8) makes the checks as documented.
  
  Sorry if I didn't explain what I meant there.  I realise that this
  pertains to ldconfig, I was trying to illustrate what checks were used
  elsewhere in the OS for shared libs.
  
  
  > Your proposal would add a large amount of overhead to program
  > execution time, and to what end?  If someone with root privileges
  > adds an untrusted directory to his LD_LIBRARY_PATH for some odd
  > reason, how are we to stop him?
  ...
  > The root user is implicitly trusted and has the privileges of all
  > the other users anyway, so you're ...um...preventing root from
  > breaking root.
  
  I see what you're saying (again I probably wasn't clear enough in what
  I meant).  I realise that compromising the LD_LIBRARY_PATH of root as
  root would accomplish nothing.  I was thinking more along the lines of
  a scenario whereby a user (admitedly in the wheel group for this
  example) has their account compromised and then su's to root.  During
  su'ing only USER, HOME & SHELL are modified and so the potentially
  tainted LD_LIBRARY_PATH is now used by root.  i.e. gaining access to
  the user account could potentially lead to escalating this to root.  
  
  I take on board your comments about increasing execution time, perhaps
  if this was a configurable/optional feature?
  
  
  > If you su to root from the account of an untrusted user, you're
  > asking for trouble anyway.  There are many documented cases of
  > people breaking root this way, and you don't even need to fiddle
  > with LD_LIBRARY_PATH.  The untrusted user just sets his PATH to
  > include a fake version of su(1) that records root's password,
  > prints ``Sorry'', and spawns the real su(1).  The correct thing to
  > do is to use su(1) only from trusted accounts.
  
  True, it was this sort of thinking that made me ponder this in the
  first place.  My thinking was that although this can be achieved as
  described, LD_LIBRARY_PATH is less checked than PATH and so is a little
  stealthier, maybe I'm wrong.
  
  I suspect that not implementing a security feature because there's
  already a similar, easier way to compromise the machine isn't the best
  reason not to do it ;)
  
  Seriously I understand what you're saying, I just thought I'd mention
  this as a potentially helpful feature.
  
  Thanks
  
    Lee
  

From: Ceri Davies <ceri@FreeBSD.org>
To: FreeBSD Gnats Submit <freebsd-gnats-submit@FreeBSD.org>
Cc:  
Subject: Re: misc/41179: LD_LIBRARY_PATH security checks
Date: Tue, 3 Jun 2003 00:04:31 +0100

 Adding to audit trail, from misfiled PR misc/52872:
 
 Date: Mon, 2 Jun 2003 10:13:44 -0700
 From: David Schultz <das@FreeBSD.org>
 Message-Id: <20030602171344.GA2249@HAL9000.homeunix.com>
 References: <200207302036.g6UKamu9051791@www.freebsd.org> <20030601181850.GA946@HAL9000.homeunix.com> <20030602161606.GA26694@nerds.org.uk>
 
  On Mon, Jun 02, 2003, Lee Brotherston wrote:
  > > If you su to root from the account of an untrusted user, you're
  > > asking for trouble anyway.  There are many documented cases of
  > > people breaking root this way, and you don't even need to fiddle
  > > with LD_LIBRARY_PATH.  The untrusted user just sets his PATH to
  > > include a fake version of su(1) that records root's password,
  > > prints ``Sorry'', and spawns the real su(1).  The correct thing to
  > > do is to use su(1) only from trusted accounts.
  > 
  > True, it was this sort of thinking that made me ponder this in the
  > first place.  My thinking was that although this can be achieved as
  > described, LD_LIBRARY_PATH is less checked than PATH and so is a little
  > stealthier, maybe I'm wrong.
  > 
  > I suspect that not implementing a security feature because there's
  > already a similar, easier way to compromise the machine isn't the best
  > reason not to do it ;)
  
  The trojan su trick can be done quite stealthily.  Many users
  already have $HOME/bin in their path, so all they need to do is
  make a $HOME/bin/su that records passwords.  An even stealthier
  tactic is to trojan the shell.  The bottom line is that if a
  user's account is compromised and someone su's to root from that
  account, the root account can be easily compromised.  In fact,
  even if your LD_LIBRARY_PATH check were implemented, an attacker
  could easily construct a trojanned binary that skipped the check.
  
  So I'm not convinced that preventing one of many avenues for such
  an attack is worthwhile.  On the other hand, you're more than
  welcome to submit patches, and others may agree with you on this
  matter.
 
State-Changed-From-To: open->suspended 
State-Changed-By: linimon 
State-Changed-When: Thu Oct 27 21:53:37 GMT 2005 
State-Changed-Why:  
There were never any patches submitted for this new feature request, 
so mark 'suspended'. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=41179 
State-Changed-From-To: suspended->closed 
State-Changed-By: arundel 
State-Changed-When: Wed Nov 24 01:47:22 UTC 2010 
State-Changed-Why:  
The situation described in this PR *only* applies to the root user. The purpose 
of running any commands as uid=0 is to have no security checks in place. 
If a regular user uses su(1) to gain root priviliges he should be aware that all 
his enviremental settings (unless su(1) was invoked with the -l switch) will 
*not* be discarded. 
The idea of adding security checks to LD_LIBRARY_PATH similar to those in 
ldconfig(8) was defenately a good idea, but since it never caught on i'll 
close this. Also even OpenBSD - famous for it's security awareness - doesn't 
seem to have incorporated this or a similar concept. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=41179 
>Unformatted:
