Last active
May 18, 2017 18:00
-
-
Save devnexen/232f4de03beddf09b4e93619d44ed8bc to your computer and use it in GitHub Desktop.
Blocking writing to a file descriptor
This file contains 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/prctl.h> | |
#include <seccomp.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
int | |
main(int argc, char *argv[]) | |
{ | |
ssize_t sz; | |
char buf[1] = { 0 }; | |
int fd = open("/tmp/foobar", O_RDWR | O_CREAT); | |
// SECCOMP works per system call | |
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM)); | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); | |
// We could have allowed write in general by setting the 4th parameter to 0 | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); | |
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); | |
seccomp_load(ctx); | |
printf("read attempt\n"); | |
sz = read(fd, buf, sizeof(buf)); | |
if (sz < 0) { | |
fprintf(stderr, "read failed %s\n", strerror(errno)); | |
goto end; | |
} | |
printf("read succesful\n"); | |
buf[0] = 'a'; | |
sz = write(fd, buf, sizeof(buf)); | |
if (errno) { | |
fprintf(stderr, "expected write failure %s\n", strerror(errno)); | |
goto end; | |
} | |
end: | |
// Any attempt to add a new privilege fails since the context has been loaded | |
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0) != -1) { | |
fprintf(stderr, "expected expanding privileges failed\n"); | |
} else { | |
printf("expanding privilege fails %s\n", strerror(errno)); | |
} | |
seccomp_release(ctx); | |
close(fd); | |
return (0); | |
} |
This file contains 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 <unistd.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
int main(int argc, char *argv[]) | |
{ | |
int fd = open("/tmp/foobar", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | |
char buf[1] = { 0 }; | |
ssize_t sz; | |
// Problem, lack of granularity since stdio includes both read and write ... | |
if (pledge("stdio", NULL) == -1) { | |
fprintf(stderr, "pledge failed %s\n", strerror(errno)); | |
exit(-1); | |
} | |
sz = read(fd, buf, sizeof(buf)); | |
if (sz < 0) { | |
fprintf(stderr, "read failed %zu, %s\n", sz, strerror(errno)); | |
exit(-1); | |
} | |
printf("read succesful\n"); | |
buf[0] = 'a'; | |
sz = write(fd, buf, sizeof(buf)); | |
// ... leads to have succesful write call | |
if (sz > 0) { | |
fprintf(stderr, "write should have failed\n"); | |
goto end; | |
} | |
printf("write had failed as expected %s\n", strerror(errno)); | |
end: | |
// But as always you cannot expand the privileges ... | |
if (pledge("stdio unix", NULL) != -1) { | |
fprintf(stderr, "pledge should have failed\n"); | |
} else { | |
printf("pledge had failed as expected %s\n", strerror(errno)); | |
} | |
printf("closing\n"); | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment