Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp406378ybi; Thu, 11 Jul 2019 21:51:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqyyUopJE3BrkjtVdZkj7l4aLKYDRPELWhlwJL1vKiJy23q8fGLIR5/NhhyndANvtTlqGAW7 X-Received: by 2002:a17:902:7202:: with SMTP id ba2mr9128534plb.266.1562907107478; Thu, 11 Jul 2019 21:51:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562907107; cv=none; d=google.com; s=arc-20160816; b=icj6UygmR5uori4VQ84BQx0y/WvJB3KS8NiLVx7tO/5pnRgiAkspU4QfX6M/UklIlc 9vgn/CRSKEgOBtDDEMA9vSZM+Ui+Vx374BMg2INox17s8WsnkICU2SUAHkSjpn0+YYyV XTaeXwWycakObSmDoTJaXH7LuL6yEi9viVZfladWc9GnbkbEs08rbJzM9xGxtmIfCuwm gBa+GSn+Lo/JKLgdt4I0zlGZaWSdaVDuG4u4fjevk8VH8sF8iWaXvdCVdl/zkvkeFrFA /U9AW9lJChFLF0/pFs0BwJsSXhiUb9qs1B5zMlUdjqNnuKds+YmLOe6EWJJ0PNvWdFyB QJ8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=cgQz34kETt8+EJWP9JrrnC/pzOFvDiF5kJrHrins7S0=; b=H0ckuLfUAW3BeOM2wAn+QKzT5mSStKwoIkpCGjaMRxJy9AxB2aBHWV+eKzCjK+tf6g uZJfg5RwRARo0OmgnOtLZDTA/FnNYw7yJrtOAMdxPl0rWH4UKCug3mOKOea8N+Qfxm2o TgGPejWIGsLiqXV2P2H8HA9gEw1w4lyym/k4LK6gahIaGDOJRMKegEY67QYHNxWpI318 lOV7aq9/QAjaPimo1ZnrlRFI6xQcZ8d3PID+fyQqg0I+J3ifMvYO5CD4KApHHtfdJ2nl 4k1uNo+zF3PHcV7ZjCPROWmHTalhHTlwpAPSCCyPZdUW436STvyyr7v00mVuBPnwi9+J aKwA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v9si6550915plp.4.2019.07.11.21.51.31; Thu, 11 Jul 2019 21:51:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729109AbfGLEPh (ORCPT + 99 others); Fri, 12 Jul 2019 00:15:37 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:60074 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727061AbfGLEPg (ORCPT ); Fri, 12 Jul 2019 00:15:36 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92 #3 (Red Hat Linux)) id 1hlmxT-000330-0Q; Fri, 12 Jul 2019 04:14:55 +0000 Date: Fri, 12 Jul 2019 05:14:54 +0100 From: Al Viro To: Aleksa Sarai Cc: Jeff Layton , "J. Bruce Fields" , Arnd Bergmann , David Howells , Shuah Khan , Shuah Khan , Andy Lutomirski , Christian Brauner , Eric Biederman , Andrew Morton , Alexei Starovoitov , Kees Cook , Jann Horn , Tycho Andersen , David Drysdale , Chanho Min , Oleg Nesterov , Aleksa Sarai , Linus Torvalds , containers@lists.linux-foundation.org, linux-alpha@vger.kernel.org, linux-api@vger.kernel.org, linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linux-mips@vger.kernel.org, linux-parisc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, linux-xtensa@linux-xtensa.org, sparclinux@vger.kernel.org Subject: Re: [PATCH v9 01/10] namei: obey trailing magic-link DAC permissions Message-ID: <20190712041454.GG17978@ZenIV.linux.org.uk> References: <20190706145737.5299-1-cyphar@cyphar.com> <20190706145737.5299-2-cyphar@cyphar.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190706145737.5299-2-cyphar@cyphar.com> User-Agent: Mutt/1.11.3 (2019-02-01) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, Jul 07, 2019 at 12:57:28AM +1000, Aleksa Sarai wrote: > @@ -514,7 +516,14 @@ static void set_nameidata(struct nameidata *p, int dfd, struct filename *name) > p->stack = p->internal; > p->dfd = dfd; > p->name = name; > - p->total_link_count = old ? old->total_link_count : 0; > + p->total_link_count = 0; > + p->acc_mode = 0; > + p->opath_mask = FMODE_PATH_READ | FMODE_PATH_WRITE; > + if (old) { > + p->total_link_count = old->total_link_count; > + p->acc_mode = old->acc_mode; > + p->opath_mask = old->opath_mask; > + } Huh? Could somebody explain why traversals of NFS4 referrals should inherit ->acc_mode and ->opath_mask? > static __always_inline > -const char *get_link(struct nameidata *nd) > +const char *get_link(struct nameidata *nd, bool trailing) > { > struct saved *last = nd->stack + nd->depth - 1; > struct dentry *dentry = last->link.dentry; > @@ -1081,6 +1134,44 @@ const char *get_link(struct nameidata *nd) > } else { > res = get(dentry, inode, &last->done); > } > + /* If we just jumped it was because of a magic-link. */ > + if (unlikely(nd->flags & LOOKUP_JUMPED)) { That's not quite guaranteed (it is possible to bind a symlink on top of a regular file, and you will get LOOKUP_JUMPED on the entry into trailing_symlink() when looking the result up). Moreover, why bother with LOOKUP_JUMPED here? See that nd->last_type = LAST_BIND; several lines prior? That's precisely to be able to recognize those suckers. And _that_ would've avoided another piece of ugliness - your LOOKUP_JUMPED kludge forces you to handle that cra^Wsclero^Wvaluable security hardening in get_link(), instead of trailing_symlink() where you apparently want it to be. Simply because nd_jump_root() done later in get_link() will set LOOKUP_JUMPED for absolute symlinks, confusing your test. Moreover, I'm not sure that trailing_symlink() is the right place for that either - I would be rather tempted to fold do_o_path() into path_openat(), inline path_lookupat() there (as in s = path_init(nd, flags); while (!(error = link_path_walk(s, nd)) && ((error = lookup_last(nd)) > 0)) { s = trailing_symlink(nd); } if (!error) error = complete_walk(nd); if (!error && nd->flags & LOOKUP_DIRECTORY) if (!d_can_lookup(nd->path.dentry)) error = -ENOTDIR; if (!error) { audit_inode(nd->name, nd->path.dentry, 0); error = vfs_open(&nd->path, file); } terminate_walk(nd); - we don't need LOOKUP_DOWN there) and then we only care about the two callers of trailing_symlink() that are in path_openat(). Which is where you have your ->acc_mode and ->opath_mask without the need to dump them into nameidata. Or to bring that mess into the things like stat(2) et.al. - it simply doesn't belong there. In any case, this "bool trailing" is completely wrong; whether that check belongs in trailing_symlink() or (some of) its callers, putting it into get_link() is a mistake, forced by kludgy check for procfs-style symlinks.