Created
June 18, 2017 20:44
-
-
Save devnexen/0ebfebfac0fa38acfb34e8f3bcf9d97d to your computer and use it in GitHub Desktop.
FreeBSD capsicum examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.