Hi, Here is a patch I use to prevent loading a shared object from a noexec mountpoint. It's an easy way, I found, after the last root exploit ((http://seclists.org/fulldisclosure/2011/Nov/452), to enhance the security of my web servers (with /home, /tmp and /var/tmp mounted with noexec).
- the last ftpd/porftpd (libc ?) exploit does not work (indirect use of rtld via nsswitch) - the previous rtld security issue should have been more difficult to use in a noexec context. - It may help to prevent some miscellaneous usage of common softwares using dlopen like apache or php. I think it also makes sens because loading a shared object sounds like a kind of "execution". What do you think about this patch and the opportunity to open a PR on this subject? Cheers Joris --- libexec/rtld-elf/rtld.c.orig 2011-12-02 12:09:40.000000000 +0100 +++ libexec/rtld-elf/rtld.c 2011-12-02 13:45:18.000000000 +0100 @@ -1123,32 +1123,50 @@ { char *pathname; char *name; + struct statfs mnt; if (strchr(xname, '/') != NULL) { /* Hard coded pathname */ + name = NULL; if (xname[0] != '/' && !trust) { _rtld_error("Absolute pathname required for shared object \"%s\"", xname); return NULL; } if (refobj != NULL && refobj->z_origin) - return origin_subst(xname, refobj->origin_path); + pathname = origin_subst(xname, refobj->origin_path); else - return xstrdup(xname); + pathname = xstrdup(xname); + } + else { /* xname is not a path */ + if (libmap_disable || (refobj == NULL) || + (name = lm_find(refobj->path, xname)) == NULL) + name = (char *)xname; + + dbg(" Searching for \"%s\"", name); + + pathname = search_library_path(name, ld_library_path); + if (pathname == NULL && refobj != NULL) + pathname = search_library_path(name, refobj->rpath); + if (pathname == NULL) + pathname = search_library_path(name, gethints()); + if (pathname == NULL) + pathname = search_library_path(name, STANDARD_LIBRARY_PATH); + } + + if (pathname != NULL) { /* noexec mountpoint in pathname */ + if (statfs(pathname, &mnt) != 0) + free(pathname); + else { + if (mnt.f_flags & MNT_NOEXEC) { + _rtld_error("noexec violation for shared object \"%s\"", pathname); + free(pathname); + return NULL; + } + else + return pathname; + } } - if (libmap_disable || (refobj == NULL) || - (name = lm_find(refobj->path, xname)) == NULL) - name = (char *)xname; - - dbg(" Searching for \"%s\"", name); - - if ((pathname = search_library_path(name, ld_library_path)) != NULL || - (refobj != NULL && - (pathname = search_library_path(name, refobj->rpath)) != NULL) || - (pathname = search_library_path(name, gethints())) != NULL || - (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) - return pathname; - if(refobj != NULL && refobj->path != NULL) { _rtld_error("Shared object \"%s\" not found, required by \"%s\"", name, basename(refobj->path)); _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"