From das@FreeBSD.ORG Sun Jun 1 11:18:52 2003 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 705C837B401 for ; Sun, 1 Jun 2003 11:18:52 -0700 (PDT) Received: from HAL9000.homeunix.com (ip232.bella-vista.sfo.interquest.net [66.199.86.232]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9C42843F75 for ; Sun, 1 Jun 2003 11:18:51 -0700 (PDT) (envelope-from das@FreeBSD.ORG) Received: from HAL9000.homeunix.com (localhost [127.0.0.1]) by HAL9000.homeunix.com (8.12.9/8.12.5) with ESMTP id h51IIpka001038; Sun, 1 Jun 2003 11:18:51 -0700 (PDT) (envelope-from das@FreeBSD.ORG) Received: (from das@localhost) by HAL9000.homeunix.com (8.12.9/8.12.5/Submit) id h51IIooD001037; Sun, 1 Jun 2003 11:18:50 -0700 (PDT) (envelope-from das@FreeBSD.ORG) Message-Id: <20030601181850.GA946@HAL9000.homeunix.com> Date: Sun, 1 Jun 2003 11:18:50 -0700 From: David Schultz To: Lee Brotherston Cc: freebsd-gnats-submit@FreeBSD.ORG In-Reply-To: <200207302036.g6UKamu9051791@www.freebsd.org> Subject: Re: LD_LIBRARY_PATH security checks References: <200207302036.g6UKamu9051791@www.freebsd.org> >Number: 52842 >Category: misc >Synopsis: Re: LD_LIBRARY_PATH security checks >Confidential: no >Severity: serious >Priority: medium >Responsible: ceri >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jun 01 11:20:10 PDT 2003 >Closed-Date: Mon Jun 02 07:17:07 PDT 2003 >Last-Modified: Mon Jun 02 07:17:07 PDT 2003 >Originator: David Schultz >Release: >Organization: >Environment: >Description: On Tue, Jul 30, 2002, Lee Brotherston wrote: > 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." ... > 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) 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. >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: State-Changed-From-To: open->closed State-Changed-By: ceri State-Changed-When: Mon Jun 2 07:16:03 PDT 2003 State-Changed-Why: Misfiled followup to misc/41179 [content migrated]. Responsible-Changed-From-To: gnats-admin->ceri Responsible-Changed-By: ceri Responsible-Changed-When: Mon Jun 2 07:16:03 PDT 2003 Responsible-Changed-Why: Take from gnats-admin. http://www.freebsd.org/cgi/query-pr.cgi?pr=52842 >Unformatted: