On Wed, Jul 18, 2018 at 01:43:40PM +0100, Al Viro wrote:

> It *is* broken.  For now leave override_creds() as in your variant, but
> we really want to deal with that crap eventually.
> 
> > Okay, so ->open() is a file op, and file ops should use file->f_cred,
> > but how are we going to enforce this?
> 
> I'd say we cut down on the use of current_cred() when deep in call chain...

Actually, how about this:

#define call_with_creds(__cred, expr) ({                \
        __typeof__(expr) ____res;                       \
        const struct cred *____old = current->cred;     \
        const struct cred *____new = (__cred);          \
        rcu_assign_pointer(current->cred, ____new);     \
        ____res = expr;                                 \
        BUG_ON(current->cred != ____new);               \
        rcu_assign_pointer(current->cred, ____old);     \
        ____res;                                        \
})

and replacing
                error = open(inode, f);
with
                error = call_with_cred(f->f_cred, open(inode, f));

possibly with similar at other methods callsites?  Unlike override_creds()
and revert_creds() it's cheap - no validation of creds, no cacheline
ping-pong...

Folks?

Reply via email to