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.