RE: Secure access to system calls for a library?
Michael Wojcik <[email protected]> Fri, 11 Jun 2004 08:28:01 -0700
| Newsgroups | gmane.comp.security.programming |
|---|---|
| Message-ID | <75C025AE395F374B81F6416B1D4BDEFB01C3BEE3@mtv-corpmail.microfocus.com> |
> From: Jonathan Leffler [mailto:[email protected]] > Sent: Wednesday, June 09, 2004 3:22 PM > > How can a library ensure that when it calls getuid(), it really calls > the system call and not a dummy provided by the application that > is using the library? A library running under the control of a hostile application, in the typical Unix environment, can't be sure of anything. What if the application overwrites data the library uses internally? What if the application dynamically loads the library, changes the page permissions, and edits the code? (Or, equivalently, makes a copy of the library, edits it on disk, and then dynamically loads the copy?) > Context: > > A library uses getuid() to establish the real user ID of the > application that is running. > The library is used by (untrustworthy) clients, and can be > included into their programs. > > There is nothing much to stop the program including: > > int main(void) > { > call_to_library_function(...); > return(0); > } > > int getuid(void) > { > return(0); > } > > Now, when the program is linked, the library gets to call the > user-defined getuid() function, not the system one. This is platform-dependent. Some Unix platforms (eg AIX) have different binding rules; some have optional binding facilities that can prevent programs from trivially interpositioning, as in your example. > AFAICS, the only reliable way for the library to know that it is really > calling the system call is for it to embed the assembler code for the > system call into its code, under its own name, and to use that name > everywhere. I'm hoping, desparately, that this is wrong. For "system calls" that are actually libc wrappers (such as getuid on Solaris), have your library dlopen /usr/lib/libc.so and dlsym the appropriate symbol, then call through the returned pointer. For system calls which are actually calls right into the kernel, on Unix implementations where system calls are made that way, nlist the kernel for the symbol in question. Details will be platform-dependent. However, this won't be sufficient to make your library secure against hostile programs. Nothing will be. Standard Unix does not provide any secure intra-process boundary mechanism. For that you have to go inter-process. A suggestion: much of what a library might do on behalf of a client can be done with a daemon, message queues, and file descriptor passing. See Stevens, _Advanced Programming in the Unix Environment_. You'd provide a library that simply communicates with the daemon. Then it doesn't matter if the application subverts the library - the library is part of the client, and the daemon assumes the entire client is insecure anyway. Subverting the library doesn't allow any escalation of privilege. -- Michael Wojcik Principal Software Systems Developer, Micro Focus