Filesystem extended attributes and Capsicum

From: Shawn Webb <shawn.webb_at_hardenedbsd.org>
Date: Fri, 22 Mar 2024 23:37:56 UTC
Hey all,

I'm writing an application in which I hope to enable Capsicum. I'm
experiencing an issue whereby extattr_get_fd fails with a file
descriptor that has all the extended attribute capabilities enabled
(CAP_EXTATTR_DELETE, CAP_EXTATTR_GET, CAP_EXTATTR_LIST, and
CAP_EXTATTR_SET).

Looking at the kernel source (sys/kern/vfs_extattr.c) tells me that
kern_extattr_get_fd only requires CAP_EXTATTR_GET.

So I'm a bit puzzled as to why my call to extattr_get_fd(2) is
failing. Am I doing something wrong or are filesystem extended
attributes not supported in a Capabilities-enabled process?

Here's how I'm creating the file descriptor (before calling
cap_enter(2)):

==== BEGIN CODE ====
static int
open_file(const char *path)
{
        cap_rights_t rights;
        int fd;

        fd = open(path, O_PATH | O_CLOEXEC);
        if (fd == -1) {
                return (-1);
        }    

        memset(&rights, 0, sizeof(rights));
        cap_rights_init(&rights, CAP_EXTATTR_DELETE, CAP_EXTATTR_GET,
            CAP_EXTATTR_LIST, CAP_EXTATTR_SET);
        cap_rights_limit(fd, &rights);

        return (fd);
}
==== END CODE ====

Eventually, after calling cap_enter(2), the following code is called:

==== BEGIN CODE ====
#define ATTRNAME_ENABLED "hbsd.pax.aslr"
        sz = extattr_get_fd(fd, ctx->hc_namespace, ATTRNAME_ENABLED, NULL, 0);
        if (sz <= 0) { 
                if (errno == ENOATTR) {
                        /*
                        * This is okay, it just means that nothing has been set.
                        * No error condition here.
                        */
                        return (RES_SUCCESS);
                }
                return (RES_FAIL);
        }
==== END CODE ====

For reference, the program's code is here:
https://git.hardenedbsd.org/shawn.webb/hbsdctrl/-/tree/main?ref_type=heads

The library code, which is what's responsible for calling the
filesystem extended attribute related syscalls is here:

https://git.hardenedbsd.org/hardenedbsd/HardenedBSD/-/tree/hardened/current/hbsdcontrol-v2/lib/libhbsdcontrol?ref_type=heads

From the rights(4) manual page, I'm instructed all I need are to apply
those capabilities to that file descriptor:

==== BEGIN PASTE ====
     CAP_EXTATTR_DELETE   Permit extattr_delete_fd(2).

     CAP_EXTATTR_GET      Permit extattr_get_fd(2).

     CAP_EXTATTR_LIST     Permit extattr_list_fd(2).

     CAP_EXTATTR_SET      Permit extattr_set_fd(2).
==== END PASTE ====

So I'm a bit unsure if I'm doing something wrong.

Thanks,

-- 
Shawn Webb
Cofounder / Security Engineer
HardenedBSD

Tor-ified Signal: +1 303-901-1600 / shawn_webb_opsec.50
https://git.hardenedbsd.org/hardenedbsd/pubkeys/-/raw/master/Shawn_Webb/03A4CBEBB82EA5A67D9F3853FF2E67A277F8E1FA.pub.asc