[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20180718181252.GU30522@ZenIV.linux.org.uk>
Date: Wed, 18 Jul 2018 19:12:52 +0100
From: Al Viro <viro@...IV.linux.org.uk>
To: Miklos Szeredi <mszeredi@...hat.com>
Cc: Stephen Rothwell <sfr@...b.auug.org.au>,
linux-fsdevel <linux-fsdevel@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>
Subject: [RFC] call_with_creds()
On Wed, Jul 18, 2018 at 05:46:09PM +0200, Miklos Szeredi wrote:
> I like the call_with_creds() idea. I didn't realize that
> override_creds()/revert_creds() can be quite heavyweight due to doing
> (unnecessary in this case) refcounting. Could use call_with_creds()
> in overlayfs too, since we hold ref on ofs->creator_cred for the
> lifetime of the filesystem.
OK...
/* expr is non-void here */
#define __call_with_creds(__cred, expr) ({ \
const struct cred *____old = current->cred; \
const struct cred *____new = __cred; \
__typeof__(expr) __res; \
rcu_assign_pointer(current->cred, ____new); \
__res = (expr); \
BUG_ON(current->cred != ____new); \
rcu_assign_pointer(current->cred, ____old); \
__res; })
/* expr for non-void, expr,0 for void */
#define __wrap_void(expr) __builtin_choose_expr( \
__builtin_types_compatible_p(__typeof__(expr), void), \
((expr),0), (expr))
/*
* Evaluate an expression with current->cred temporary set to __cred.
* NOTE: expr must not result in changed ->cred - any changes during
* its evaluation must be undone.
*/
#define call_with_creds(__cred, expr) \
((__typeof__(expr))__call_with_creds(__cred, __wrap_void(expr)))
Linus, David - do you have any objections to the above? I would like
to do some of the file method calls via that - e.g. have callers of
->write() (both __vfs_write() and do_loop_readv_writev()) use
nr = call_with_creds(file->f_cred,
file->f_op->write(file, iovec.iov_base,
iovec.iov_len, ppos));
instead of
nr = file->f_op->write(file, iovec.iov_base,
iovec.iov_len, ppos));
Ditto for call of open() in do_dentry_open(), etc.
Powered by blists - more mailing lists