>Synopsis:      pledge allows /dev/null to be any file type
>Category:      kernel
>Environment:
        System      : OpenBSD 7.2
        Details     : OpenBSD 7.2 (GENERIC.MP) #2: Thu Nov 24 23:53:03 MST 2022
                         
r...@syspatch-72-arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP

        Architecture: OpenBSD.arm64
        Machine     : arm64
>Description:
        I was testing pledge on a 7.2 system and as a test opened /dev/null.
I was astonished that it didn't abort.  OK perhaps it needs to do that but
doesn't it work better if /dev/null is major/minor (2,2) device?  I have a 
ktrace for you to show what I mean.
>How-To-Repeat:
spica# mkdir dev      
mkdir: dev: File exists
spica# touch dev/null
spica# ktrace -i ./testprog
spica# ls -l dev/null
-rw-r--r--  1 root  pjp  5 Mar 19 22:51 dev/null
spica# cat dev/null
test
spica# 

The ktrace I'm gonna edit it to show only the juicy parts:

 13252 testprog CALL  chroot(0x995cc0ea640)
 13252 testprog NAMI  "/home/pjp"
 13252 testprog RET   chroot 0
 13252 testprog CALL  kbind(0x7f7fffff95b8,24,0xd10fcc1b312a79c0)
 13252 testprog RET   kbind 0
 13252 testprog CALL  chdir(0x995cc0ea64a)
 13252 testprog NAMI  "/"
 13252 testprog RET   chdir 0
 13252 testprog CALL  kbind(0x7f7fffff95b8,24,0xd10fcc1b312a79c0)
 13252 testprog RET   kbind 0
 13252 testprog CALL  pledge(0x995cc0ea652,0)
 13252 testprog STRU  promise="stdio"
 13252 testprog RET   pledge 0
 13252 testprog CALL  kbind(0x7f7fffff95b8,24,0xd10fcc1b312a79c0)
 13252 testprog RET   kbind 0
 13252 testprog CALL  open(0x995cc0ea658,0x1<O_WRONLY>)
 13252 testprog NAMI  "/dev/null"
 13252 testprog RET   open 4
 13252 testprog CALL  kbind(0x7f7fffff95b8,24,0xd10fcc1b312a79c0)
 13252 testprog RET   kbind 0
 13252 testprog CALL  write(4,0x995cc0ea64c,0x5)
 13252 testprog GIO   fd 4 wrote 5 bytes
       "test

So writing to a file called {CHROOT}/dev/null is allowed on stdio pledge.
This is very suboptimal to me.  Can't it perform a check for major 2, minor 2?

spica# ls -l /dev/null
crw-rw-rw-  1 root  wheel    2,   2 Mar 19 10:14 /dev/null

>Fix:
>From github I got this for the HEAD of CVS from:

https://github.com/openbsd/src/blob/master/sys/kern/kern_pledge.c


----->
        case SYS_open:
                /* daemon(3) or other such functions */
                if ((ni->ni_pledge & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 &&
                    strcmp(path, "/dev/null") == 0) {
                        ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
                        return (0);
                }
<------

I figure that's the code for this, partially.  But someone else would surely
know better.  And has surely a better fix on hand?


dmesg:
see previous reports.

Reply via email to