rtld and noexec

Alexander Kabaev kabaev at gmail.com
Fri Dec 2 22:03:55 UTC 2011


On Fri, 2 Dec 2011 18:22:57 +0100
joris dedieu <joris.dedieu at gmail.com> wrote:

> 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));
> _______________________________________________


1. There is a race using statfs and then loading the file.
2. We already have the check in  do_load_object


-- 
Alexander Kabaev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 188 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20111202/7972a7e5/signature.pgp


More information about the freebsd-hackers mailing list