From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/125 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Daily reports: Friday (threaded setuid testing) Date: Sun, 10 Jul 2011 10:52:01 -0400 Message-ID: <20110710145201.GB133@brightrain.aerifal.cx> References: <4E125DBC.9090809@gmail.com> <4E131E8F.9@gmail.com> <4E14C55E.6030808@gmail.com> <4E16141F.5060303@gmail.com> <4E17877E.30907@gmail.com> <20110709115301.GA6510@openwall.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1310310101 26296 80.91.229.12 (10 Jul 2011 15:01:41 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 10 Jul 2011 15:01:41 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-209-gllmg-musl=m.gmane.org@lists.openwall.com Sun Jul 10 17:01:36 2011 Return-path: Envelope-to: gllmg-musl@lo.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by lo.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1QfvVm-0004av-Rw for gllmg-musl@lo.gmane.org; Sun, 10 Jul 2011 17:01:35 +0200 Original-Received: (qmail 14191 invoked by uid 550); 10 Jul 2011 15:01:33 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 14183 invoked from network); 10 Jul 2011 15:01:32 -0000 Content-Disposition: inline In-Reply-To: <20110709115301.GA6510@openwall.com> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:125 Archived-At: On Sat, Jul 09, 2011 at 03:53:01PM +0400, Solar Designer wrote: > Luka, Rich - > > On Sat, Jul 09, 2011 at 12:41:02AM +0200, Luka Mar??eti?? wrote: > > I wanted to move on to task number 8, but I had some questions. I asked > > Rich via XMPP about them, but I guess he's still out. > > OK, let's wait for Rich's comments on this. BTW, chances are that the > RLIMIT_NPROC check on setuid(2) and friends will be removed from future > kernels: http://www.openwall.com/lists/kernel-hardening/2011/07/06/8 I wonder if I should jump in that thread and mention that, even if the application checks the return value of setuid, it can be wrong for multi-threaded applications... Or at least I believe it can. I think proving that it can be wrong with glibc would still be a really nice task to get done in cluts, and it would establish the usefulness of cluts to the community outside of just advancing musl towards 1.0. Luka, to answer your questions from chat: 1. Yes, an otherwise-unused account (actually just uid number; it doesn't need any files, homedir, etc.) is required for testing. This should be configurable eventually, but hard-coding some oddball value near the max uid would probably be sufficient for now. 2. An ordinary user can lower their RLIMIT_NPROCS, but you'll be doing this before dropping root, not after. 3. Each thread does not need to call setuid (the library function); rather setuid (the library function itself) jumps through hoops to make every thread call the setuid syscall. The unfortunate situation is that each thread's syscall can independently succeed or fail, and glibc only reports the status of one of them (the last one, I believe, which is also the thread that called the setuid library function). 4. Your goal (at least for catching the bug believed to exist in glibc and which musl hopefully does not shared) is to cause some of the setuid syscalls to fail, but the last one to succeed. This will require very [un]lucky timing, so the test probably needs to run many times. - RLIMIT_NPROCS should be greater than the number of threads you'll be testing with. - When setuid (the library function) is first called, the number of processes with the target uid should already be equal (or just under) RLIMIT_NPROCS due to having forked some children in advance and set their uid to the target uid. - These children should attempt to terminate themselves after the parent (with all its threads) calls setuid, but before all threads get scheduled and have a chance to make the setuid syscall. This way, some threads may fail, but the last one should succeed. - After setuid (library function) returns, you check its return value and have each thread call getuid to check that they all have the target uid or that the library function returned failure. If the library function returned success but some threads still have uid=0, this is a potentially-serious security bug. Does this make sense? By the way, there's no exact science to when the children should terminate. The best I can think of is to run the test repeatedly with varying (extremely short) delays, probably just spinning in userspace or making a single call to sched_yield. You might also want to vary the number of threads, and note that it may be easier or harder with the number very small (e.g. equal to the number of cores). > I understand that Rich's proposed tests are about the libc wrapper > functions that are thread-aware rather than about syscalls, yet I felt > the above was relevant to the tests. If the syscalls were correct (process-global) it would be a non-issue, and if they could not fail due to RLIMIT_NPROC, it would also be a non-issue. But as the kernel currently works (or rather doesn't work), the userspace has to put a lot of effort into changing uids safely... Rich