Do not allow setting O_REMCLO with fcntl()
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 9 Jan 2017 14:07:41 +0000 (09:07 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 10 Jan 2017 00:01:40 +0000 (19:01 -0500)
The rule with setting remove-on-close for a chan/FD is:

"You can only set REMCLO if you are allowed to remove."

It's up to the individual devices that support REMCLO to ensure this is
true.  Devices from Plan 9 should already have done that, though who
knows.  However, those old devices did not have fcntl()/dev.chan_ctl(),
so they definitely would not have checked that angle.

Regardless of old devices, allowing fcntl() to toggle REMCLO could still
be dangerous.  Consider a process that has a shared FD, but can't walk
to the path of the chan.  Now it can potentially remove a file it
couldn't name.  I'm not sure we want to allow that.

Finally, the main aspect of the rule (which isn't enforced in this
patch, but devices need to control) is that you can set REMCLO only if
you can remove.  If a process could set REMCLO without permission, then
it could share the FD/chan with another process who does have
permission, and then when that process closes the FD, it could trigger a
remove.  This is a 'confused deputy' scenario.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/ns/sysfile.c

index dd1d77a..4c52336 100644 (file)
@@ -1400,6 +1400,8 @@ int fd_setfl(int fd, int flags)
                /* TODO: The whole CCEXEC / O_CLOEXEC on 9ns needs work */
                error(EINVAL, "can't toggle O_CLOEXEC with setfl");
        }
+       if (cexternal_flags_differ(flags, c->flag, O_REMCLO))
+               error(EINVAL, "can't toggle O_REMCLO with setfl");
        if (cexternal_flags_differ(flags, c->flag, O_PATH))
                error(EINVAL, "can't toggle O_PATH with setfl");
        /* Devices can do various prep work, including RPCs to other servers (#mnt)