From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by kanga.kvack.org (Postfix) with ESMTP id E133E6B0253 for ; Thu, 19 Nov 2015 19:41:18 -0500 (EST) Received: by wmww144 with SMTP id w144so1115570wmw.1 for ; Thu, 19 Nov 2015 16:41:18 -0800 (PST) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org. [140.211.169.12]) by mx.google.com with ESMTPS id n10si14841058wja.51.2015.11.19.16.41.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Nov 2015 16:41:17 -0800 (PST) Date: Thu, 19 Nov 2015 16:41:14 -0800 From: Andrew Morton Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Message-Id: <20151119164114.6b55662050922bfa45de3a94@linux-foundation.org> In-Reply-To: <20151120001043.GA28204@www.outflux.net> References: <20151120001043.GA28204@www.outflux.net> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org List-ID: To: Kees Cook Cc: linux-kernel@vger.kernel.org, Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , linux-mm@kvack.org On Thu, 19 Nov 2015 16:10:43 -0800 Kees Cook wrote: > Normally, when a user can modify a file that has setuid or setgid bits, > those bits are cleared when they are not the file owner or a member of the > group. This is enforced when using write() directly but not when writing > to a shared mmap on the file. This could allow the file writer to gain > privileges by changing the binary without losing the setuid/setgid bits. > > Signed-off-by: Kees Cook > Cc: stable@vger.kernel.org > --- > mm/memory.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/mm/memory.c b/mm/memory.c > index deb679c31f2a..4c970a4e0057 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, > > if (!page_mkwrite) > file_update_time(vma->vm_file); > + file_remove_privs(vma->vm_file); > } > > return VM_FAULT_WRITE; file_remove_privs() is depressingly heavyweight. You'd think there was some more lightweight way of caching the fact that we've already done this. Dumb question: can we run file_remove_privs() once, when the file is opened writably, rather than for each and every write into each page? Also, the proposed patch drops the file_remove_privs() return value on the floor and we just go ahead with the modification. How come? -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-f175.google.com (mail-io0-f175.google.com [209.85.223.175]) by kanga.kvack.org (Postfix) with ESMTP id E553D6B0253 for ; Thu, 19 Nov 2015 19:52:03 -0500 (EST) Received: by ioir85 with SMTP id r85so108320247ioi.1 for ; Thu, 19 Nov 2015 16:52:03 -0800 (PST) Received: from mail-ig0-x236.google.com (mail-ig0-x236.google.com. [2607:f8b0:4001:c05::236]) by mx.google.com with ESMTPS id 17si421856igi.57.2015.11.19.16.52.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Nov 2015 16:52:03 -0800 (PST) Received: by igl9 with SMTP id 9so912972igl.0 for ; Thu, 19 Nov 2015 16:52:03 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <20151119164114.6b55662050922bfa45de3a94@linux-foundation.org> References: <20151120001043.GA28204@www.outflux.net> <20151119164114.6b55662050922bfa45de3a94@linux-foundation.org> Date: Thu, 19 Nov 2015 16:52:02 -0800 Message-ID: Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap From: Kees Cook Content-Type: text/plain; charset=UTF-8 Sender: owner-linux-mm@kvack.org List-ID: To: Andrew Morton Cc: LKML , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , Linux-MM On Thu, Nov 19, 2015 at 4:41 PM, Andrew Morton wrote: > On Thu, 19 Nov 2015 16:10:43 -0800 Kees Cook wrote: > >> Normally, when a user can modify a file that has setuid or setgid bits, >> those bits are cleared when they are not the file owner or a member of the >> group. This is enforced when using write() directly but not when writing >> to a shared mmap on the file. This could allow the file writer to gain >> privileges by changing the binary without losing the setuid/setgid bits. >> >> Signed-off-by: Kees Cook >> Cc: stable@vger.kernel.org >> --- >> mm/memory.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/mm/memory.c b/mm/memory.c >> index deb679c31f2a..4c970a4e0057 100644 >> --- a/mm/memory.c >> +++ b/mm/memory.c >> @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, >> >> if (!page_mkwrite) >> file_update_time(vma->vm_file); >> + file_remove_privs(vma->vm_file); >> } >> >> return VM_FAULT_WRITE; > > file_remove_privs() is depressingly heavyweight. You'd think there was > some more lightweight way of caching the fact that we've already done > this. In theory, the IS_NOSEC(inode) should be fast. Perhaps track it in the vma or file struct? > Dumb question: can we run file_remove_privs() once, when the file is > opened writably, rather than for each and every write into each page? This got discussed briefly, but I can't remember why it got shot down. > Also, the proposed patch drops the file_remove_privs() return value on > the floor and we just go ahead with the modification. How come? Oh, excellent catch. If it can't drop it, it shouldn't be writable. I'm not sure what the right abort scenario is in wp_page_reuse. Maybe move this to start of wp_page_shared instead? -Kees -- Kees Cook Chrome OS Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ig0-f180.google.com (mail-ig0-f180.google.com [209.85.213.180]) by kanga.kvack.org (Postfix) with ESMTP id D86386B0253 for ; Thu, 19 Nov 2015 20:03:16 -0500 (EST) Received: by igcph11 with SMTP id ph11so1046654igc.1 for ; Thu, 19 Nov 2015 17:03:16 -0800 (PST) Received: from mail-ig0-x232.google.com (mail-ig0-x232.google.com. [2607:f8b0:4001:c05::232]) by mx.google.com with ESMTPS id mw6si506294igb.4.2015.11.19.17.03.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Nov 2015 17:03:16 -0800 (PST) Received: by igbxm8 with SMTP id xm8so1184691igb.1 for ; Thu, 19 Nov 2015 17:03:16 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <20151120010016.GB31694@1wt.eu> References: <20151120001043.GA28204@www.outflux.net> <20151120010016.GB31694@1wt.eu> Date: Thu, 19 Nov 2015 17:03:15 -0800 Message-ID: Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap From: Kees Cook Content-Type: text/plain; charset=UTF-8 Sender: owner-linux-mm@kvack.org List-ID: To: Willy Tarreau Cc: LKML , Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , Linux-MM On Thu, Nov 19, 2015 at 5:00 PM, Willy Tarreau wrote: > Hi Kees, > > On Thu, Nov 19, 2015 at 04:10:43PM -0800, Kees Cook wrote: >> Normally, when a user can modify a file that has setuid or setgid bits, >> those bits are cleared when they are not the file owner or a member of the >> group. This is enforced when using write() directly but not when writing >> to a shared mmap on the file. This could allow the file writer to gain >> privileges by changing the binary without losing the setuid/setgid bits. >> >> Signed-off-by: Kees Cook >> Cc: stable@vger.kernel.org >> --- >> mm/memory.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/mm/memory.c b/mm/memory.c >> index deb679c31f2a..4c970a4e0057 100644 >> --- a/mm/memory.c >> +++ b/mm/memory.c >> @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, >> >> if (!page_mkwrite) >> file_update_time(vma->vm_file); >> + file_remove_privs(vma->vm_file); > > I thought you said in one of the early mails of this thread that it > didn't work. Or maybe I misunderstood. I had a think-o in my earlier attempts. I understood the meaning of page_mkwrite incorrectly. > Also, don't you think we should move that into the if (!page_mkwrite) > just like for the time update ? Nope, page_mkwrite indicates if there was a vmops call to page_mkwrite. In this case, it means "I will update the file time if the filesystem driver didn't take care of it like it should". For file_remove_privs, we want to always do it, since we should not depend on filesystems to do it. -Kees -- Kees Cook Chrome OS Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f44.google.com (mail-wm0-f44.google.com [74.125.82.44]) by kanga.kvack.org (Postfix) with ESMTP id 544BF6B0253 for ; Thu, 19 Nov 2015 20:15:56 -0500 (EST) Received: by wmec201 with SMTP id c201so1958819wme.1 for ; Thu, 19 Nov 2015 17:15:56 -0800 (PST) Received: from 1wt.eu (wtarreau.pck.nerim.net. [62.212.114.60]) by mx.google.com with ESMTP id m135si712329wmb.47.2015.11.19.17.15.55 for ; Thu, 19 Nov 2015 17:15:55 -0800 (PST) Date: Fri, 20 Nov 2015 02:03:11 +0100 From: Willy Tarreau Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Message-ID: <20151120010311.GA31728@1wt.eu> References: <20151120001043.GA28204@www.outflux.net> <20151120010016.GB31694@1wt.eu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120010016.GB31694@1wt.eu> Sender: owner-linux-mm@kvack.org List-ID: To: Kees Cook Cc: linux-kernel@vger.kernel.org, Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , linux-mm@kvack.org On Fri, Nov 20, 2015 at 02:00:16AM +0100, Willy Tarreau wrote: > > diff --git a/mm/memory.c b/mm/memory.c > > index deb679c31f2a..4c970a4e0057 100644 > > --- a/mm/memory.c > > +++ b/mm/memory.c > > @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, > > > > if (!page_mkwrite) > > file_update_time(vma->vm_file); > > + file_remove_privs(vma->vm_file); > > I thought you said in one of the early mails of this thread that it > didn't work. Or maybe I misunderstood. OK never mind for this one I just saw the other mail where you said the test is OK now. But I'm still worried about the performance so the other point below remains : > Also, don't you think we should move that into the if (!page_mkwrite) > just like for the time update ? Thanks! Willy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f41.google.com (mail-wm0-f41.google.com [74.125.82.41]) by kanga.kvack.org (Postfix) with ESMTP id EA3DB6B0254 for ; Thu, 19 Nov 2015 20:15:56 -0500 (EST) Received: by wmec201 with SMTP id c201so51464441wme.0 for ; Thu, 19 Nov 2015 17:15:56 -0800 (PST) Received: from 1wt.eu (wtarreau.pck.nerim.net. [62.212.114.60]) by mx.google.com with ESMTP id m135si712329wmb.47.2015.11.19.17.15.55 for ; Thu, 19 Nov 2015 17:15:55 -0800 (PST) Date: Fri, 20 Nov 2015 02:00:16 +0100 From: Willy Tarreau Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Message-ID: <20151120010016.GB31694@1wt.eu> References: <20151120001043.GA28204@www.outflux.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120001043.GA28204@www.outflux.net> Sender: owner-linux-mm@kvack.org List-ID: To: Kees Cook Cc: linux-kernel@vger.kernel.org, Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , linux-mm@kvack.org Hi Kees, On Thu, Nov 19, 2015 at 04:10:43PM -0800, Kees Cook wrote: > Normally, when a user can modify a file that has setuid or setgid bits, > those bits are cleared when they are not the file owner or a member of the > group. This is enforced when using write() directly but not when writing > to a shared mmap on the file. This could allow the file writer to gain > privileges by changing the binary without losing the setuid/setgid bits. > > Signed-off-by: Kees Cook > Cc: stable@vger.kernel.org > --- > mm/memory.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/mm/memory.c b/mm/memory.c > index deb679c31f2a..4c970a4e0057 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, > > if (!page_mkwrite) > file_update_time(vma->vm_file); > + file_remove_privs(vma->vm_file); I thought you said in one of the early mails of this thread that it didn't work. Or maybe I misunderstood. Also, don't you think we should move that into the if (!page_mkwrite) just like for the time update ? Willy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by kanga.kvack.org (Postfix) with ESMTP id 2CBBC6B0255 for ; Thu, 19 Nov 2015 20:15:59 -0500 (EST) Received: by wmww144 with SMTP id w144so1739373wmw.1 for ; Thu, 19 Nov 2015 17:15:58 -0800 (PST) Received: from 1wt.eu (wtarreau.pck.nerim.net. [62.212.114.60]) by mx.google.com with ESMTP id m135si712329wmb.47.2015.11.19.17.15.56 for ; Thu, 19 Nov 2015 17:15:56 -0800 (PST) Date: Fri, 20 Nov 2015 02:06:24 +0100 From: Willy Tarreau Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Message-ID: <20151120010624.GA31732@1wt.eu> References: <20151120001043.GA28204@www.outflux.net> <20151120010016.GB31694@1wt.eu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Sender: owner-linux-mm@kvack.org List-ID: To: Kees Cook Cc: LKML , Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , Linux-MM On Thu, Nov 19, 2015 at 05:03:15PM -0800, Kees Cook wrote: > On Thu, Nov 19, 2015 at 5:00 PM, Willy Tarreau wrote: > > Hi Kees, > > > > On Thu, Nov 19, 2015 at 04:10:43PM -0800, Kees Cook wrote: > >> Normally, when a user can modify a file that has setuid or setgid bits, > >> those bits are cleared when they are not the file owner or a member of the > >> group. This is enforced when using write() directly but not when writing > >> to a shared mmap on the file. This could allow the file writer to gain > >> privileges by changing the binary without losing the setuid/setgid bits. > >> > >> Signed-off-by: Kees Cook > >> Cc: stable@vger.kernel.org > >> --- > >> mm/memory.c | 1 + > >> 1 file changed, 1 insertion(+) > >> > >> diff --git a/mm/memory.c b/mm/memory.c > >> index deb679c31f2a..4c970a4e0057 100644 > >> --- a/mm/memory.c > >> +++ b/mm/memory.c > >> @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, > >> > >> if (!page_mkwrite) > >> file_update_time(vma->vm_file); > >> + file_remove_privs(vma->vm_file); > > > > I thought you said in one of the early mails of this thread that it > > didn't work. Or maybe I misunderstood. > > I had a think-o in my earlier attempts. I understood the meaning of > page_mkwrite incorrectly. > > > Also, don't you think we should move that into the if (!page_mkwrite) > > just like for the time update ? > > Nope, page_mkwrite indicates if there was a vmops call to > page_mkwrite. In this case, it means "I will update the file time if > the filesystem driver didn't take care of it like it should". For > file_remove_privs, we want to always do it, since we should not depend > on filesystems to do it. Ah OK, thanks for the explanation, I didn't understand it like this at all last time I read it. Cheers, Willy -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f43.google.com (mail-wm0-f43.google.com [74.125.82.43]) by kanga.kvack.org (Postfix) with ESMTP id 3EFF86B0038 for ; Mon, 23 Nov 2015 07:26:29 -0500 (EST) Received: by wmec201 with SMTP id c201so102689075wme.1 for ; Mon, 23 Nov 2015 04:26:28 -0800 (PST) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id v20si18858670wjq.230.2015.11.23.04.26.28 for (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Nov 2015 04:26:28 -0800 (PST) Date: Mon, 23 Nov 2015 13:26:24 +0100 From: Jan Kara Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Message-ID: <20151123122624.GI23418@quack.suse.cz> References: <20151120001043.GA28204@www.outflux.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120001043.GA28204@www.outflux.net> Sender: owner-linux-mm@kvack.org List-ID: To: Kees Cook Cc: linux-kernel@vger.kernel.org, Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , linux-mm@kvack.org On Thu 19-11-15 16:10:43, Kees Cook wrote: > Normally, when a user can modify a file that has setuid or setgid bits, > those bits are cleared when they are not the file owner or a member of the > group. This is enforced when using write() directly but not when writing > to a shared mmap on the file. This could allow the file writer to gain > privileges by changing the binary without losing the setuid/setgid bits. > > Signed-off-by: Kees Cook > Cc: stable@vger.kernel.org So I had another look at this and now I understand why we didn't do it from the start: To call file_remove_privs() safely, we need to hold inode->i_mutex since that operations is going to modify file mode / extended attributes and i_mutex protects those. However we cannot get i_mutex in the page fault path as that ranks above mmap_sem which we hold during the whole page fault. So calling file_remove_privs() when opening the file is probably as good as it can get. It doesn't catch the case when suid bits / IMA attrs are set while the file is already open but I don't see easy way around this. BTW: This is another example where page fault locking is constraining us and life would be simpler for filesystems we they get called without mmap_sem held... Honza -- Jan Kara SUSE Labs, CR -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pa0-f48.google.com (mail-pa0-f48.google.com [209.85.220.48]) by kanga.kvack.org (Postfix) with ESMTP id 053CB6B0038 for ; Mon, 23 Nov 2015 07:55:02 -0500 (EST) Received: by padhx2 with SMTP id hx2so190613797pad.1 for ; Mon, 23 Nov 2015 04:55:01 -0800 (PST) Received: from out02.mta.xmission.com (out02.mta.xmission.com. [166.70.13.232]) by mx.google.com with ESMTPS id 4si19291861pfq.125.2015.11.23.04.55.01 for (version=TLS1_2 cipher=AES128-SHA bits=128/128); Mon, 23 Nov 2015 04:55:01 -0800 (PST) From: ebiederm@xmission.com (Eric W. Biederman) References: <20151120001043.GA28204@www.outflux.net> <20151123122624.GI23418@quack.suse.cz> Date: Mon, 23 Nov 2015 06:34:06 -0600 In-Reply-To: <20151123122624.GI23418@quack.suse.cz> (Jan Kara's message of "Mon, 23 Nov 2015 13:26:24 +0100") Message-ID: <87lh9odhdt.fsf@x220.int.ebiederm.org> MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap Sender: owner-linux-mm@kvack.org List-ID: To: Jan Kara Cc: Kees Cook , linux-kernel@vger.kernel.org, Andrew Morton , Dave Chinner , Andy Lutomirski , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , Serge Hallyn , linux-mm@kvack.org Jan Kara writes: > On Thu 19-11-15 16:10:43, Kees Cook wrote: >> Normally, when a user can modify a file that has setuid or setgid bits, >> those bits are cleared when they are not the file owner or a member of the >> group. This is enforced when using write() directly but not when writing >> to a shared mmap on the file. This could allow the file writer to gain >> privileges by changing the binary without losing the setuid/setgid bits. >> >> Signed-off-by: Kees Cook >> Cc: stable@vger.kernel.org > > So I had another look at this and now I understand why we didn't do it from > the start: > > To call file_remove_privs() safely, we need to hold inode->i_mutex since > that operations is going to modify file mode / extended attributes and > i_mutex protects those. However we cannot get i_mutex in the page fault > path as that ranks above mmap_sem which we hold during the whole page > fault. > > So calling file_remove_privs() when opening the file is probably as good as > it can get. It doesn't catch the case when suid bits / IMA attrs are set > while the file is already open but I don't see easy way around this. Could we perhaps do this on mmap MAP_WRITE instead of open, and simply deny adding these attributes if a file is mapped for write? That would seem to be a little more compatible with what we already do, and guards against the races you mention as well. Eric -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kees Cook Subject: [PATCH] fs: clear file set[ug]id when writing via mmap Date: Thu, 19 Nov 2015 16:10:43 -0800 Message-ID: <20151120001043.GA28204@www.outflux.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org Cc: Andrew Morton , Dave Chinner , Andy Lutomirski , Jan Kara , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , LKML , "Eric W . Biederman" List-Id: linux-mm.kvack.org Normally, when a user can modify a file that has setuid or setgid bits, those bits are cleared when they are not the file owner or a member of the group. This is enforced when using write() directly but not when writing to a shared mmap on the file. This could allow the file writer to gain privileges by changing the binary without losing the setuid/setgid bits. Signed-off-by: Kees Cook Cc: stable@vger.kernel.org --- mm/memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/memory.c b/mm/memory.c index deb679c31f2a..4c970a4e0057 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2036,6 +2036,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, if (!page_mkwrite) file_update_time(vma->vm_file); + file_remove_privs(vma->vm_file); } return VM_FAULT_WRITE; -- 1.9.1 -- Kees Cook Chrome OS Security From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ig0-f170.google.com (mail-ig0-f170.google.com [209.85.213.170]) by kanga.kvack.org (Postfix) with ESMTP id D93486B0038 for ; Wed, 2 Dec 2015 18:55:02 -0500 (EST) Received: by igvg19 with SMTP id g19so1648515igv.1 for ; Wed, 02 Dec 2015 15:55:02 -0800 (PST) Received: from mail-io0-x231.google.com (mail-io0-x231.google.com. [2607:f8b0:4001:c06::231]) by mx.google.com with ESMTPS id m26si8961489ioi.105.2015.12.02.15.55.02 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Dec 2015 15:55:02 -0800 (PST) Received: by ioc74 with SMTP id 74so63697986ioc.2 for ; Wed, 02 Dec 2015 15:55:02 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <20151123122624.GI23418@quack.suse.cz> References: <20151120001043.GA28204@www.outflux.net> <20151123122624.GI23418@quack.suse.cz> Date: Wed, 2 Dec 2015 15:55:01 -0800 Message-ID: Subject: Re: [PATCH] fs: clear file set[ug]id when writing via mmap From: Kees Cook Content-Type: text/plain; charset=UTF-8 Sender: owner-linux-mm@kvack.org List-ID: To: Jan Kara Cc: LKML , Andrew Morton , Dave Chinner , Andy Lutomirski , "Kirill A. Shutemov" , Mel Gorman , Johannes Weiner , Rik van Riel , Matthew Wilcox , Shachar Raindel , Boaz Harrosh , Michal Hocko , Haggai Eran , Theodore Tso , Willy Tarreau , Dirk Steinmetz , Michael Kerrisk-manpages , Serge Hallyn , Seth Forshee , Alexander Viro , Linux FS Devel , "Eric W . Biederman" , Serge Hallyn , Linux-MM On Mon, Nov 23, 2015 at 4:26 AM, Jan Kara wrote: > On Thu 19-11-15 16:10:43, Kees Cook wrote: >> Normally, when a user can modify a file that has setuid or setgid bits, >> those bits are cleared when they are not the file owner or a member of the >> group. This is enforced when using write() directly but not when writing >> to a shared mmap on the file. This could allow the file writer to gain >> privileges by changing the binary without losing the setuid/setgid bits. >> >> Signed-off-by: Kees Cook >> Cc: stable@vger.kernel.org > > So I had another look at this and now I understand why we didn't do it from > the start: > > To call file_remove_privs() safely, we need to hold inode->i_mutex since > that operations is going to modify file mode / extended attributes and > i_mutex protects those. However we cannot get i_mutex in the page fault > path as that ranks above mmap_sem which we hold during the whole page > fault. Ah, I see the notation in __generic_file_write_iter about i_mutex. Should file_remove_privs() get some debug annotation to catch callers that don't hold that mutex? (That would have alerted me much earlier.) > So calling file_remove_privs() when opening the file is probably as good as > it can get. It doesn't catch the case when suid bits / IMA attrs are set > while the file is already open but I don't see easy way around this. I agree with Eric: mmap time seems like the right place. > BTW: This is another example where page fault locking is constraining us > and life would be simpler for filesystems we they get called without > mmap_sem held... > > Honza > -- > Jan Kara > SUSE Labs, CR -Kees -- Kees Cook Chrome OS & Brillo Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org