Skip to content

Instantly share code, notes, and snippets.

@devnexen
Created June 18, 2017 20:44
Show Gist options
  • Select an option

  • Save devnexen/0ebfebfac0fa38acfb34e8f3bcf9d97d to your computer and use it in GitHub Desktop.

Select an option

Save devnexen/0ebfebfac0fa38acfb34e8f3bcf9d97d to your computer and use it in GitHub Desktop.
FreeBSD capsicum examples
#include <sys/capsicum.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
int c, errs;
u_int mod;
errs = errno;
if ((c = cap_enter()) != 0) {
fprintf(stderr, "cap_enter failed: %s\n", strerror(errno));
errno = errs;
goto end;
}
// subsequent calls of cap_enter is safe
cap_enter();
if ((c = cap_getmode(&mod)) != 0) {
fprintf(stderr, "cap_getmode failed: %s\n", strerror(errno));
errno = errs;
goto end;
}
printf("cap_getmode %senabled\n", (mod == 0 ? "dis" : ""));
end:
return (c);
}
#include <sys/capsicum.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
int c, errs, fd;
char buf[1] = { 0 };
ssize_t sz;
cap_rights_t r;
errs = errno;
if ((c = cap_enter()) != 0) {
fprintf(stderr, "cap_enter failed: %s\n", strerror(errno));
errno = errs;
goto end;
}
if ((fd = open("/tmp/foobar", O_RDONLY)) < 0) {
fprintf(stderr, "open failed: %s\n", strerror(errno));
c = fd;
errno = errs;
goto end;
}
cap_rights_init(&r, CAP_READ);
if ((c = cap_rights_limit(fd, &r)) != 0) {
fprintf(stderr, "cap_rights_limit failed: %s\n", strerror(errno));
errno = errs;
goto end;
}
sz = read(fd, buf, sizeof(buf));
if (sz < 0) {
fprintf(stderr, "read shoud have succeeded\n");
goto end;
}
printf("read succesful\n");
buf[0] = 'a';
sz = write(fd, buf, sizeof(buf));
if (sz > 0) {
fprintf(stderr, "write %ld should not have happened\n", sz);
goto end;
}
printf("capsicum did its job cannot write on this file descriptor\n");
end:
// We cannot expand rights ...
cap_rights_set(&r, CAP_READ, CAP_WRITE);
fprintf(stderr, "%s\n", strerror(errno));
errs = errno;
if (fd != -1)
close(fd);
return (c);
}
#include <libcasper.h>
#include <casper/cap_dns.h>
#include <sys/capsicum.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
cap_channel_t *root, *dns;
const char *t[1];
int f[1];
const char *ipv6 = "::1";
struct in6_addr addr;
root = cap_init();
if (root == NULL) {
fprintf(stderr, "cap_init failed %s\n", strerror(errno));
exit(-1);
}
cap_enter();
dns = cap_service_open(root, "system.dns");
cap_close(root);
if (dns == NULL) {
fprintf(stderr, "cap_service_open failed %s\n", strerror(errno));
goto end;
}
// Only dns resolution for IPV4 addresses allowed here ...
t[0] = "ADDR";
f[0] = AF_INET;
cap_dns_type_limit(dns, t, 1);
cap_dns_family_limit(dns, f, 2);
inet_pton(AF_INET6, ipv6, &addr);
if (gethostbyaddr(&addr, sizeof(addr), AF_INET6) != NULL) {
fprintf(stderr, "cap_gethostbyaddr should have failed\n");
} else {
printf("::1 not resolved as expected\n");
}
end:
return (0);
}
@alisarctl
Copy link
Copy Markdown

I had a look into example2, it is clearly wrong and does not work and it does not demonstrate the usage of capsicum.

The call to open should be performed before the call to cap_enter, otherwise it fails. Also open should be called with read write flag set (O_RDWR), otherwise the call to write always fail with "Bad file descriptor" error.

Putting open before cap_enter with O_RDWR flag, demonstrate how the capsicum implementation block the write call for insufficient capabilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment