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
>>

Reply via email to