Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031177AbbDWWJH (ORCPT ); Thu, 23 Apr 2015 18:09:07 -0400 Received: from mail-lb0-f169.google.com ([209.85.217.169]:36440 "EHLO mail-lb0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030888AbbDWWJC (ORCPT ); Thu, 23 Apr 2015 18:09:02 -0400 MIME-Version: 1.0 In-Reply-To: References: From: Andy Lutomirski Date: Thu, 23 Apr 2015 15:08:39 -0700 Message-ID: Subject: Re: Sharing credentials in general (Re: [GIT PULL] kdbus for 4.1-rc1) To: Linus Torvalds Cc: Greg Kroah-Hartman , Andrew Morton , Arnd Bergmann , "Eric W. Biederman" , One Thousand Gnomes , Tom Gundersen , Jiri Kosina , "linux-kernel@vger.kernel.org" , Daniel Mack , David Herrmann , Djalal Harouni Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5077 Lines: 104 On Thu, Apr 23, 2015 at 2:05 PM, Linus Torvalds wrote: > On Thu, Apr 23, 2015 at 12:41 PM, Andy Lutomirski wrote: >> Objection 2: There's a difference between the printer daemon knowing >> that Angry Penguins has general permission to print and an explicit >> assertion by Angry Penguins of its permission to print. > > Now, this I don't necessarily agree with. Simply because what you > propose seems to require everybody to do something extra, and that > adds complexity. > > When you open a file, you don't object to the fact that the VFS layer > uses your privileges to check whether you can do that. It would be > insane to say that the open system call should have an explicit > argument saying that the vfs layer should take your privileges into > account. > > (Which is not to say that that _can_ make sense - if you implement a > server in user space, you might want an interface that says "open > using these credentials". So such a model is not insane per se, but it > *does* imply a lot more complexity, and there's a reason we don't do > that. We *have* done user-level file servers in Linux, and the way it > was done was that the open system call uses the current thread > privileges implicitly, and the server that wants to do the odd and > complex unusual thing has to explicitly modify its privileges around > the open call!). > > So I think your second argument is weak. It doesn't actually match > what we do normally in Unix. Yes, the mindset _can_ make sense, but > it's different from normal behavior, and it's not at all clear that it > is a good thing, because it introduces new issues and complexities > along the lines of "how do I assert that I want you to check my > credentials for *this* particular use (printing) but not for *that* > particular use (passwd). > > IOW, your model seems to imply that you have to surround everything > with yet another layer of enumeration of all the possible things you > might want to do. And that seems just a bad idea to me. Why would > system daemon permissions be so magically different from all the > *native* permission handling we do? > > It's not like you open /etc/passwd with some special flag that says "I > want to edit my password". No. You open /etc/passwd with the normal > unix credentials. In the case of open, though, users know, or at least should know, that open(2) checks fsuid, fsgid, LSM labels, and effective caps. If you want to open with less than your full privileges, you need to change fsuid (setresuid or setfsuid) and fsgid. If you're not aware of capabilities, that's enough -- we have very careful code that makes sure of this, because the alternative would break things. (This is all the setuid fixup mess in commoncap.c.) We *need* that code because there is a large installed code base from the non-Linux or non-caps world that things that setresuid + open is safe. If you're caps-aware, then you do a prctl to tell the system that and you mess with effective caps. Still good. With LSMs, it gets murky, but we trust the writers of policies to get this right by magic or by patching every daemon on their system [1]. As a result of all this, we really can't get away with adding a new per-task bit "can feed walruses" that's checked on open because setresuid won't temporary clear it and vsftpd might start inadvertently feeding walruses. We can, however, safely add such a bit and check it on a brand-new call feed_walruses(2) or in a hypothetical open("/walrus/mouth", O_ASSERT_FEED_WALRUS_PRIVILEGE) call. [2] Now let's consider write(2). write(2) doesn't check privileges, per POSIX. We've screwed that up multiple times by having write(2) check privileges, generally resulting in root holes. IOW, userspace programmers who type open(...) are supposed to know that they're asserting their euid and egid, and those programmers are supposed to know that when they type write(...) they aren't asserting caps at all. Enter kdbus. We now have an unbounded number of possible kdbus calls, and somehow users are supposed to keep track of which privileges the hold affect which kdbus calls. Either each method should document which privileges it looks at (and then carefully never change it or, if they do, carefully fix up the holes a la the setuid fixup) [3], or the library should just suck it up and make users assert privileges explicitly. I strongly favor the latter. [1] I don't believe that this actually works in practice. Fortunately, good LSM users design their systems so that a complete failure of LSM policy still leaves it secure. [2] In the capability-based-security model, which I'm increasingly a fan of, this looks like openat(walrus_privilege_fd, "mouth", O_RDWR). Isn't that nifty? [3] Of course multiple people will mess this up. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/