11

I am trying to use LD_PRELOAD to preload a library with an application that has setuid permissions. Tried LD_PRELOAD at first, and it seemed like it was being ignored with the setuid binary, though it was working when I tried it with others like ls, dir etc.

From the documentation of LD_PRELOAD:

   LD_PRELOAD
          A whitespace-separated list of additional, user-specified, ELF shared
          libraries to be loaded before all others.  This can be used to
          selectively override functions in other shared libraries.  For set-
          user-ID/set-group-ID ELF binaries, only libraries in the standard
          search directories that are also set-user-ID will be loaded.

I tried to put the library in /usr/lib, /usr/local/lib, and /usr/lib64 with setuid permissions as per this documentation above, but it still doesnt seem to work. If I dont give LD_PRELOAD a path in the case where I have the library in the standard dirs with setuid, it cannot seem to find the library. If I give it the path, it does not do anything.

The setuid binary is a root permissions binary that runs in a non root user shell. Any thoughts? Not sure if I am missing a path, an environment variable, or I am misunderstanding the documentation above.

Edit: permissions as requested are:

Library:

-rwsr-sr-x 1 root root 72580 2012-02-10 07:51

App:

-rwsr-xr-x 1 root root 137517601 2012-02-10 

env | grep LD
LD_LIBRARY_PATH=/usr/lib (I added this manually myself, usually LD_LIBRARY_PATH is empty)
Zsolt Botykai
  • 46,263
  • 14
  • 81
  • 102
Mark Lobo
  • 311
  • 2
  • 3
  • 8

5 Answers5

14

LD_PRELOAD cannot be used with setuid. This is a security feature in linux. For reference check this article, which goes into the detail on how to use LD_PRELOAD to substitute some library calls with custom code, at the example of malloc.

Jonas Schäfer
  • 18,084
  • 5
  • 49
  • 67
user1259893
  • 189
  • 1
  • 4
5

If you are using SELinux, this may be due to it. One of the ELF auxiliary vectors that glibc supports is AT_SECURE. This particular parameter (which is either 0 by default or 1) tells the ELF dynamic linker to unset various environment variables that are considered potentially harmful for your system. One of these is LD_PRELOAD. Normally, this environment sanitation is done when a setuid/setgid application is called (to prevent the obvious vulnerabilities). SELinux also enhanced this sanitation to whenever an application is triggering a domain transition in SELinux (say sysadm_t to mozilla_t through a binary labelled moz, or whatever); SELinux sets the AT_SECURE flag for the loaded application (in the example, mozilla/firefox).

The noatsecure permission disables the environment sanitation activity for a particular transition. You can do this through the following allow statement (as it would apply on the example above):

allow sysadm_t mozilla_t:process { noatsecure };
Michael Foukarakis
  • 35,789
  • 5
  • 74
  • 113
  • Is selinux security enhanced linux or suse enterprise? Im running the latter. Does what you mentioned still apply for suse enterprise? – Mark Lobo Feb 13 '12 at 18:49
  • According to [this](http://news.opensuse.org/2008/08/20/opensuse-to-add-selinux-basic-enablement-in-111/) SELinux is an option in SUSE Enterprise starting with 11.1. If you're not using it, however, my answer doesn't apply. – Michael Foukarakis Feb 13 '12 at 19:02
  • From what I can see, I am not running Selinux. I dont see any of the usual selinux configuration options. I did see AppArmour, but its disabled as well. – Mark Lobo Feb 14 '12 at 03:25
0

On a system with glibc, you can preload a library using another supported way: by adding the library into /etc/ld.so.preload. This one doesn't suffer from the restrictions of LD_PRELOAD.

In particular, this way I was able to preload (uselessly, just to demonstrate that it works) libgtk3-nocsd.so into /usr/bin/passwd, and, when I ran passwd ruslan, the library did show up in /proc/<PID_OF_PASSWD>/maps while passwd was waiting for current password input.

One shortcoming is that you can't do this on a per-app basis like you could with LD_PRELOAD. If you really require this, maybe you could change your library to try to check whether it wants to do anything, based on what path to current process binary is (detecting it like discussed here).

Ruslan
  • 15,183
  • 5
  • 55
  • 110
0

LD_PRELOAD can't be used with set-user-ID/set-group-ID program, except that the et-user-ID/set-group-ID program is running as the same real and effective user and group.

For example, after fork and before exec*, setting

  • setreuid to the owner of the set-user-ID program
  • setregid to the group of the set-group-ID program
Like
  • 1,298
  • 12
  • 21
-1

Install your lib as such:

  • location: /lib or /usr/lib
  • permissions: root:root
  • has setuid and setgid on

Make sure LD_PRELOAD is exported to your environment

$ export LD_PRELOAD=/usr/lib/yourlib.so
$ env | grep LD_PRELOAD  # verify

Then run your program.

Christopher Neylan
  • 7,455
  • 3
  • 34
  • 50
  • It doesnt work, and it applies athe library to _all_ apps. I was trying to use LD_PRELOAD=... appname to just preload it for this app. As an experiment, I copied ls into my own dir, and added setuid permissions to it(chmod u+s ./ls). My library used to work with ls before, doesnt work with this local permissions changed one anymore.:( As another experiment, I tried adding the lib to /etc/ld.so.preload, and it works, but again, its for all apps. I wanted it to work with LD_PRELOAD=.. appname if possible. – Mark Lobo Feb 10 '12 at 21:25
  • can you edit to show the result of `ls -lad` on your lib and your program, as well as the result of `env | grep LD`? – Christopher Neylan Feb 10 '12 at 21:26
  • Added the edit. Thanks for your help! Just one more clarification, when I put it in /etc/ld.so.preload, my app also seems to work with the lib, it just works for all apps. Maybe some checks the loader does as part of LD_PRELOAD are skipped in the ld.so.preload case. Also, when I sudo and run as root, LD_PRELOAD works with my app, but I cannot run the app as root unfortunately. This was just a quick experiment. – Mark Lobo Feb 10 '12 at 21:36