You should note of course that LD_PRELOAD will not work for any setuid or setgid binary. Users thus cannot do anything they wouldn't have been able to do otherwise by modifying code or compiling their own using this trick. I agree that LD_PRELOAD is very easy to use, but vendors shipping statically linked binaries is a big inconvenience, and I don't believe they should do it on account of the LD_PRELOAD hack. It's just not worth it. Here are some of the disadvantages of a statically linked binary: - It's big on disk. Not only that but if there are multiple binaries that share code (and what two binaries don't share at least code from libc?), the size of this code is multiplied by the number of binaries. - It's big in memory. Same argument, but this time regarding code that it duplicated in memory (shared libraries are mapped only once) - It's compatible with only one version of the operating system. (libc's kernel interfaces are always free to change) - The binary won't benefit from bugfixes in the vendor's system libraries. - In many cases, it may not even be possible. For example, in Solaris, using the name service switch REQUIRES a dynamically linked binary, and keep in mind that you need the name service switch for all getXXXbyYYY() functions. In fact, it's not hard using gdb and breakpoints to override any desired function in statically linked binaries too. (Harder if it's stripped, admitedly). If you must, extract those functions which you consider critical from libc.a, and link those into the main binary (or even use syscall() directly, but please link your stuff dynamically! I assume that in your original message you are referring to an example of using time() for a task such as forcing a demo copy of software to expire (and overriding time() to fool the scheme). Similar situations occur with binaries that check a machine's hostid or IP address to verify license to use it. In all these cases, if you are writing software that does this, and you want to protect yourself from people bypassing your tests, you definately need to contort your code a bit. If there's a function called check_license() and a user can overwrite the beginning of this function with code for "return 0" and that totally bypasses all your checks, then you got fooled pretty easily. I suggest the following: - Check this inside main() or some other big long function to discourage disassembly/decompilation. - Arrange that it is not possible to bypass your checks by nopping out a single function/function call - Don't print a message immediately after you do the checks. The user will be able to set a breakpoint at the place where you print your message (since you ultimately have to make a system call to print text) and know pretty much what section of your code is making the checks. Tangeant: On Solaris, you can override the system call of your choice by making a kernel module that goes in the kernel/sys subdirectory. I do not have documentation as to how that's done, but this method of overriding a system call is virtually undetectable by user level software. On OSes where you have source, of course, you're free to modify system calls with even more ease! -Phil > Many UNIX systems allow you to "pre-load" shared libraries by setting > an environment variable LD_PRELOAD. This allows you to do interesting > things like replace standard C library functions or even the C > interfaces to system calls with your own functions. > > I recently ran across a piece of software which depended upon knowing > the time reasonably accurately. By replacing the time(2) UNIX system > call with my own function, I was able to fool the program and get it > to misbehave, without the inconvenience of actually changing the system > time or even requiring root privileges. > > If you are writing programs which depend on C library functions or > UNIX system calls for secure operation, please distribute only > statically-linked versions, as the effort to fool statically-linked > binaries is a lot higher than a simple LD_PRELOAD spoof.
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:45:55 PDT