From: phil-news-nospam on
Is there a way I can verify file ownership of a dynamic library I will be
opening with dlopen()? If the program that is opening it is running suid,
especially suid root, I want to be sure the library is owned by the suid'd
effective user. In particular, I want to be sure the library links cannot
be switched around between stat() and dlopen(). If this were just open(),
I could do fstat() on the descriptor to be really sure. Something like
fdopen() but for a library ... like fdlopen() ... would be nice. But I
don't see such a thing around.

--
-----------------------------------------------------------------------------
| Phil Howard KA9WGN | http://linuxhomepage.com/ http://ham.org/ |
| (first name) at ipal.net | http://phil.ipal.org/ http://ka9wgn.ham.org/ |
-----------------------------------------------------------------------------
From: Måns Rullgård on
phil-news-nospam(a)ipal.net writes:

> Is there a way I can verify file ownership of a dynamic library I will be
> opening with dlopen()? If the program that is opening it is running suid,
> especially suid root, I want to be sure the library is owned by the suid'd
> effective user. In particular, I want to be sure the library links cannot
> be switched around between stat() and dlopen(). If this were just open(),
> I could do fstat() on the descriptor to be really sure. Something like
> fdopen() but for a library ... like fdlopen() ... would be nice. But I
> don't see such a thing around.

I'm not aware of such a thing either. One possible solution which
comes to my mind is to intercept calls to open() and do the
verification there, i.e. call the real open(), fstat(), and return the
fd only if the file has the right owner, otherwise closing it and
returning -1.

--
M�ns Rullg�rd
mans(a)mansr.com
From: William Ahern on
phil-news-nospam(a)ipal.net wrote:
> Is there a way I can verify file ownership of a dynamic library I will be
> opening with dlopen()? If the program that is opening it is running suid,
> especially suid root, I want to be sure the library is owned by the suid'd
> effective user. In particular, I want to be sure the library links cannot
> be switched around between stat() and dlopen(). If this were just open(),
> I could do fstat() on the descriptor to be really sure. Something like
> fdopen() but for a library ... like fdlopen() ... would be nice. But I
> don't see such a thing around.

The following code worked for me on OS X, Linux, and OpenBSD without
modification, excepting the original library path. Obvious caveats would be
inability to work in a chroot jail without /dev/fd visibility, and at
least on OpenBSD /dev/fd entries are static device files so it wouldn't work
if the fd was too high--on a vanilla OpenBSD install over 64.

#include <stdlib.h>
#include <stdio.h>

#include <fcntl.h>

#include <dlfcn.h>

#include <err.h>

int main(void) {
char path[256] = "/usr/local/lib/libyaml.so.0.0";
char name[64] = "yaml_get_version_string";
int fd;
void *lib;
const char *(*getver)(void);

if (-1 == (fd = open(path, O_RDONLY)))
err(EXIT_FAILURE, "%s", path);

snprintf(path, sizeof path, "/dev/fd/%d", fd);

if (!(lib = dlopen(path, RTLD_NOW)))
errx(EXIT_FAILURE, "%s: %s", path, dlerror());

if (!(getver = dlsym(lib, name)))
errx(EXIT_FAILURE, "%s: %s", name, dlerror());

printf("%s\n", getver());

return 0;
}
From: David Schwartz on
On May 4, 6:27 pm, phil-news-nos...(a)ipal.net wrote:

> Is there a way I can verify file ownership of a dynamic library I will be
> opening with dlopen()?  If the program that is opening it is running suid,
> especially suid root, I want to be sure the library is owned by the suid'd
> effective user.  In particular, I want to be sure the library links cannot
> be switched around between stat() and dlopen().  If this were just open(),
> I could do fstat() on the descriptor to be really sure.  Something like
> fdopen() but for a library ... like fdlopen() ... would be nice.  But I
> don't see such a thing around.

I think it's likely a better idea to check the ownership and
permissions of the directory the library is in before calling
'dlopen'. The ownership of the file doesn't really say much about
whether it's safe to use for the purpose it's being used anyway.

DS
From: Nicolas George on
David Schwartz wrote in message
<f37d8057-9e6b-4e9a-a6fd-4371dadd683e(a)k25g2000prh.googlegroups.com>:
> I think it's likely a better idea to check the ownership and
> permissions of the directory the library is in before calling
> 'dlopen'.

He needs to check every path element that leads to the library, because
either one could be a symlink.

And the check must be aware of the local system's rules for permissions. For
example, just checking the file mode may not be enough if there are ACLs.

He also needs to check that the library has no runtime dependency towards
untrusted paths. For example, with modern automagic tools, if someone
compiles with --prefix=/tmp/install and then moves the installation (he'd
rather use DESTDIR, of course), he can get RPATH=/tmp/install/lib in some of
his libraries.

Even if the library is in a completely trusted path and does not have
structural dependencies towards untrusted paths, it could be a completely
unrelated library unsuited to run in a SUID environment. Some libraries, for
example, parse some specific environment variable in their _init function.