All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miklos Szeredi <mszeredi@redhat.com>,
	Stephen Rothwell <sfr@canb.auug.org.au>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [RFC] call_with_creds()
Date: Wed, 18 Jul 2018 20:46:37 +0100	[thread overview]
Message-ID: <20180718194637.GV30522@ZenIV.linux.org.uk> (raw)
In-Reply-To: <CA+55aFxh62Yttq-W2Cr_YQQ5tAL1xjijjnaz1-zdZNqZPQFM0g@mail.gmail.com>

On Wed, Jul 18, 2018 at 11:19:18AM -0700, Linus Torvalds wrote:
> On Wed, Jul 18, 2018 at 11:13 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> > Linus, David - do you have any objections to the above?
> 
> I damn well do.
> 
> I explained earlier why it's wrong and fragile, and why it can just
> cause the *reverse* security problem if you do it wrong. So now you
> take a subtle bug, and make it even more subtle, and encourage people
> to do this known-broken model of using creds at IO time.
> 
> No.
> 
> Some debugging option to just clear current->creds entirely and catch
> mis-uses, sure. But saying "we have shit buggy garbage in random write
> functions, so we'll just paper over it"? No.

Huh?  Nevermind ->write(), what about open()?  Here's a specific question
Miklos brought when I suggested to get rid of that override:
/*
 * These allocate and release file read/write context information.
 */
int nfs_open(struct inode *inode, struct file *filp)
{
        struct nfs_open_context *ctx;

        ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp);

struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
                                                fmode_t f_mode,
                                                struct file *filp)
{
        struct nfs_open_context *ctx;
        struct rpc_cred *cred = rpc_lookup_cred();

struct rpc_cred *rpc_lookup_cred(void)
{
        return rpcauth_lookupcred(&generic_auth, 0);

struct rpc_cred *
rpcauth_lookupcred(struct rpc_auth *auth, int flags)
{
        struct auth_cred acred;
        struct rpc_cred *ret;
        const struct cred *cred = current_cred();

How should we bring the cred passed to do_dentry_open() where open() has been
called to rpcauth_lookupcred() where we end up looking for rpc_cred by what
should've been the cred passed to do_dentry_open() and is, instead, current_cred()?

We can pass filp->f_cred to rpc_lookup_cred() variant that gets it as an explicit
argument and feed it down to rpcauth_lookupcred() variant that does the same.
We can basically ignore the ->f_cred here.  Or we can get current_cred() equal
to ->f_cred for the duration of open().

I'd probably prefer the first variant, but the last part of the question Miklos
asked
> Okay, so ->open() is a file op, and file ops should use file->f_cred,
> but how are we going to enforce this?
is not trivial - how do we find the places where that kind of thing happens and
what do we do in the meanwhile?  I don't see any quick answers - any suggestions
would be very welcome.  It's not just direct current_cred() callers; that stuff
gets called deep in call chains.  And lifting it all the way up means a lot of
methods that need to get an explicit struct cred * argument.  Are you OK with
going in that direction?

I'm honestly not sure - it's not an attempt to maneuver you into changing your
policy re ->write().  Do we care about ->f_cred at all and if we do, how do we
get it consistent across the filesystems?  I'd buy "it's a weird and obscure thing"
for overlayfs, but that example is on NFS...

We definitely do have bugs in that area - consider e.g.
static int ecryptfs_threadfn(void *ignored)
{
        set_freezable();
        while (1)  {
                struct ecryptfs_open_req *req;

                wait_event_freezable(
                        ecryptfs_kthread_ctl.wait,
                        (!list_empty(&ecryptfs_kthread_ctl.req_list)
                         || kthread_should_stop()));
                mutex_lock(&ecryptfs_kthread_ctl.mux);
                if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
                        mutex_unlock(&ecryptfs_kthread_ctl.mux);
                        goto out;
                }
                while (!list_empty(&ecryptfs_kthread_ctl.req_list)) {
                        req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
                                               struct ecryptfs_open_req,
                                               kthread_ctl_list);
                        list_del(&req->kthread_ctl_list);
                        *req->lower_file = dentry_open(&req->path,
                                (O_RDWR | O_LARGEFILE), current_cred());
                        complete(&req->done);
                }
                mutex_unlock(&ecryptfs_kthread_ctl.mux);
        }
out:
        return 0;
}

It's a kernel thread, so current_cred() looks bogus...

  reply	other threads:[~2018-07-18 20:26 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-10  0:17 linux-next: manual merge of the vfs tree with the overlayfs tree Stephen Rothwell
2018-07-10 15:04 ` Al Viro
2018-07-11  2:11   ` Al Viro
2018-07-11  2:21     ` [RFC][PATCH 01/42] drm_mode_create_lease_ioctl(): fix open-coded filp_clone_open() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 02/42] cxl_getfile(): fix double-iput() on alloc_file() failures Al Viro
2018-07-11  2:21       ` [RFC][PATCH 03/42] ocxlflash_getfile(): " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 04/42] make get_empty_filp() to call file_free_rcu() directly Al Viro
2018-07-11  2:35         ` Linus Torvalds
2018-07-11  2:43           ` Al Viro
2018-07-11  2:21       ` [RFC][PATCH 05/42] fold security_file_free() into file_free() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 06/42] turn filp_clone_open() into inline wrapper for dentry_open() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 07/42] create_pipe_files(): use fput() if allocation of the second file fails Al Viro
2018-07-11  2:21       ` [RFC][PATCH 08/42] make sure do_dentry_open() won't return positive as an error Al Viro
2018-07-11  2:39         ` Linus Torvalds
2018-07-11  2:41           ` Al Viro
2018-07-11  2:21       ` [RFC][PATCH 09/42] pass creds to get_empty_filp(), make sure dentry_open() passes the right creds Al Viro
2018-07-11  2:21       ` [RFC][PATCH 10/42] get rid of cred argument of vfs_open() and do_dentry_open() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 11/42] security_file_open(): lose cred argument Al Viro
2018-07-11  2:21       ` [RFC][PATCH 12/42] ->file_open(): " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 13/42] introduce FMODE_OPENED Al Viro
2018-07-11  2:21       ` [RFC][PATCH 14/42] fold put_filp() into fput() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 15/42] lift fput() on late failures into path_openat() Al Viro
2018-07-11  5:43         ` Amir Goldstein
2018-07-11  2:21       ` [RFC][PATCH 16/42] now we can fold open_check_o_direct() into do_dentry_open() Al Viro
2018-07-11  2:44         ` Linus Torvalds
2018-07-11  2:59           ` Al Viro
2018-07-11  3:13             ` Linus Torvalds
2018-07-11  2:21       ` [RFC][PATCH 17/42] switch all remaining checks for FILE_OPENED to FMODE_OPENED Al Viro
2018-07-11  2:21       ` [RFC][PATCH 18/42] introduce FMODE_CREATED and switch to it Al Viro
2018-07-11  2:21       ` [RFC][PATCH 19/42] IMA: don't propagate opened through the entire thing Al Viro
2018-07-11  2:21       ` [RFC][PATCH 20/42] getting rid of 'opened' argument of ->atomic_open() - step 1 Al Viro
2018-07-11  2:21       ` [RFC][PATCH 21/42] getting rid of 'opened' argument of ->atomic_open() - part 2 Al Viro
2018-07-11  2:21       ` [RFC][PATCH 22/42] get rid of 'opened' argument of ->atomic_open() - part 3 Al Viro
2018-07-11  2:21       ` [RFC][PATCH 23/42] get rid of 'opened' in path_openat() and the helpers downstream Al Viro
2018-07-11  2:21       ` [RFC][PATCH 24/42] ->atomic_open(): return 0 in all success cases Al Viro
2018-07-11  2:21       ` [RFC][PATCH 25/42] document ->atomic_open() changes Al Viro
2018-07-11  2:21       ` [RFC][PATCH 26/42] switch atomic_open() and lookup_open() to returning 0 in all success cases Al Viro
2018-07-11  2:21       ` [RFC][PATCH 27/42] kill FILE_{CREATED,OPENED} Al Viro
2018-07-11  2:21       ` [RFC][PATCH 28/42] new wrapper: alloc_file_pseudo() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 29/42] __shmem_file_setup(): reorder allocations Al Viro
2018-07-11  2:21       ` [RFC][PATCH 30/42] ... and switch shmem_file_setup() to alloc_file_pseudo() Al Viro
2018-07-11  2:21       ` [RFC][PATCH 31/42] cxl_getfile(): switch " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 32/42] ocxlflash_getfile(): " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 33/42] hugetlb_file_setup(): " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 34/42] anon_inode_getfile(): " Al Viro
2018-07-11  2:21       ` [RFC][PATCH 35/42] create_pipe_files(): switch the first allocation " Al Viro
2018-07-11  2:22       ` [RFC][PATCH 36/42] new helper: alloc_file_clone() Al Viro
2018-07-11  2:22       ` [RFC][PATCH 37/42] do_shmat(): grab shp->shm_file earlier, switch to alloc_file_clone() Al Viro
2018-07-11  2:22       ` [RFC][PATCH 38/42] make alloc_file() static Al Viro
2018-07-11  2:22       ` [RFC][PATCH 39/42] document alloc_file() changes Al Viro
2018-07-11  2:22       ` [RFC][PATCH 40/42] make path_init() unconditionally paired with terminate_walk() Al Viro
2018-07-11  2:22       ` [RFC][PATCH 41/42] allow link_path_walk() to take ERR_PTR() Al Viro
2018-07-11  2:22       ` [RFC][PATCH 42/42] few more cleanups of link_path_walk() callers Al Viro
2018-07-11  2:56       ` [RFC][PATCH 01/42] drm_mode_create_lease_ioctl(): fix open-coded filp_clone_open() Linus Torvalds
2018-07-11 15:25         ` Al Viro
2018-07-11 16:15           ` Al Viro
2018-07-12 12:43             ` Al Viro
2018-07-12 15:05               ` Linus Torvalds
2018-07-12 15:53                 ` vfs / overlayfs conflict resolution for linux-next Al Viro
2018-07-18  2:56                   ` Al Viro
2018-07-18  3:29                     ` Stephen Rothwell
2018-07-18  7:25                       ` Miklos Szeredi
2018-07-18 12:10                         ` Miklos Szeredi
2018-07-18 12:43                           ` Al Viro
2018-07-18 13:46                             ` Al Viro
2018-07-18 15:46                             ` Miklos Szeredi
2018-07-18 18:12                               ` [RFC] call_with_creds() Al Viro
2018-07-18 18:19                                 ` Linus Torvalds
2018-07-18 19:46                                   ` Al Viro [this message]
2018-07-18 19:53                                     ` Linus Torvalds
2018-07-18 20:04                                       ` Al Viro
2018-07-18 20:15                                         ` Al Viro
2018-07-18 20:43                                         ` Linus Torvalds
2018-07-18 21:22                                           ` Al Viro
2018-07-18 23:06                                             ` Linus Torvalds
2018-07-18 21:27                                           ` David Howells
2018-07-18 23:16                                             ` Linus Torvalds
2018-07-18 21:28                                   ` David Howells
2018-07-18 23:13                                     ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180718194637.GV30522@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mszeredi@redhat.com \
    --cc=sfr@canb.auug.org.au \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.