Hi, It unfortunately is not that simple to me. Because I don't have any getpw* code really. But when I take getpw out of pledge it aborts the program upon execution like so:
beta# rbdaemon -s 192.168.35.4 mkdir: File exists Abort trap (core dumped) beta# dmesg|tail -1 rbdaemon(73308): syscall 33 "getpw" beta# cd - /home/pjp/Src/sources/Net/rbdaemon beta# grep pledge\( rbdaemon.c if (pledge("stdio cpath rpath wpath inet dns exec proc", NULL) < 0) { So pledge requires that I have getpw. I feel like i'm caught in a catch22. This is a backup program that I'M building.. I'm putting the code up (it's ugly) you can read it here: http://centroid.eu/private/rbdaemon.c.txt I know I'M shamed now, but this is something I cooked up over the weekend. I can after all hoist the reading of these particular files above pledge() but cpio(1) will still fail because it's pledged similar, at least that's what I noticed when I removed pledge() from this program to test. Question then is... is cpio(1) pledged wrong? Regards, -peter On 10/23/17 18:06, Theo de Raadt wrote: > That is working as intended. > > Hoist the pw lookup up ahead. > > Our base doesn't have a single program which needs access to the > password hash after pledge, so your program doesn't need it either. > >> I'm debugging a program that doesn't work around reading /etc/spwd.db. In >> a ktrace it gives this: >> >> 78130 rbdaemon CALL open(0xeca79d7b000,0<O_RDONLY>) >> 78130 rbdaemon NAMI "/etc/spwd.db" >> 78130 rbdaemon RET open -1 errno 1 Operation not permitted >> >> When I take the pledge code out which is: >> >> if (pledge("stdio cpath rpath wpath inet dns exec getpw proc", NULL)... >> >> Then the program gets further but stalls upon the forked executed cpio that >> it calls (cpio is reading /etc/spwd.db). >> >> It took me ages to find out it's a pledge that's doing it and I looked at >> this >> code and it looks like this in /sys/kern/kern_pledge.c: >> >> /* getpw* and friends need a few files */ >> if ((ni->ni_pledge == PLEDGE_RPATH) && >> (p->p_p->ps_pledge & PLEDGE_GETPW)) { >> if (strcmp(path, "/etc/spwd.db") == 0) >> return (EPERM); /* don't call pledge_fail */ >> if (strcmp(path, "/etc/pwd.db") == 0) >> return (0); >> if (strcmp(path, "/etc/group") == 0) >> return (0); >> if (strcmp(path, "/etc/netid") == 0) >> return (0); >> } >> >> So it shows that this is where the EPERM is coming from. So I have to >> question >> the logic of this statement, if we have "rpath getpw" then return EPERM on >> /etc/spwd.db reads. Is that right? >> >> should it not be '!(p->p_p->ps_pledge & PLEDGE_GETPW)' here? So as to, if we >> have rpath in our pledges and don't have getpw then EPERM on spwd.db reads? >> >> Funnily what's happening now is to the contrary of the manpage to getpw: >> >> getpw This allows read-only opening of files in /etc for the >> getpwnam(3), getgrnam(3), getgrouplist(3), and >> initgroups(3) family of functions. They may also need to >> operate in a yp(8) environment, so a successful open(2) >> of >> /var/run/ypbind.lock enables inet operations. >> >> Maybe I'm reading all code wrong, so how would I fix this? I just need to >> somehow read these files...and be pledged. >> >> My system is 6.2. >> >> Regards, >> -peter >>