Solved libcasper sysctl access broken?

There's an example in the man page for cap_sysctl() that outlines how to access sysctl while in capabilities mode after enabling capsicum(). However, no matter what I do, I can no longer read or write anything using those capability functions. The regular sysctl facility is no longer accessible either, for obvious reasons.

I've copied that example verbatim, it gives me "Operation not permitted", even if I run the compiled code as root in securelevel -1 in a regular system (not in a jail). Does anyone of you have any ideas, what might be missing here? Do I need to enable any services to get libcasper to run? Some slide decks on the web are talking about "casperd" but I couldn't find anything on my system pointing to a service.

Appreciate any help.

The code in question for reference:
Code:
    cap_channel_t *capcas, *capsysctl;
     const char *name = "kern.trap_enotcap";
     nvlist_t *limits;
     int value;
     size_t size;

     /* Open capability to Casper. */
     capcas = cap_init();
     if (capcas == NULL)
             err(1, "Unable to contact Casper");

     /* Enter capability mode sandbox. */
     if (cap_enter() < 0 && errno != ENOSYS)
             err(1, "Unable to enter capability mode");

     /* Use Casper capability to create capability to the system.sysctl service. */
     capsysctl = cap_service_open(capcas, "system.sysctl");
     if (capsysctl == NULL)
             err(1, "Unable to open system.sysctl service");

     /* Close Casper capability, we don't need it anymore. */
     cap_close(capcas);

     /* Create limit for one MIB with read access only. */
     limits = nvlist_create(0);
     nvlist_add_number(limits, name, CAP_SYSCTL_READ);

     /* Limit system.sysctl. */
     if (cap_limit_set(capsysctl, limits) < 0)
             err(1, "Unable to set limits");

     /* Fetch value. */
     if (cap_sysctlbyname(capsysctl, name, &value, &size, NULL, 0) < 0)
             err(1, "Unable to get value of sysctl");

     printf("The value of %s is %d.\n", name, value);

     cap_close(capsysctl);
    exit(0);
 
casperd and related usage libcapsicum were removed maybe 6 years ago or more (guess), so no, there's no daemon you need.
Capsicum is one of those notoriously poorly (yes, it's contentious) documented facilities provided by FreeBSD; probably because it's hard to implement well.

Anyway, this can't be your entire code. What are your includes? Have you #define WITH_CASPER?
 
Oh my god, this is such a stupid thing to miss; yes - I forgot #define WITH_CASPER. That's fixed it.
I should have figured that something was off when the compiler told me that cap_systemctlbyname was an alias for systemctlbyname.

Agree on the documentation; once you get the hang of capsicum, it totally makes sense though.
 
Back
Top