From owner-svn-src-all@freebsd.org Mon Dec 28 21:15:47 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A0A8FA54B44; Mon, 28 Dec 2015 21:15:47 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail104.syd.optusnet.com.au (mail104.syd.optusnet.com.au [211.29.132.246]) by mx1.freebsd.org (Postfix) with ESMTP id 46F72130E; Mon, 28 Dec 2015 21:15:46 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id B6A36426246; Tue, 29 Dec 2015 08:15:37 +1100 (AEDT) Date: Tue, 29 Dec 2015 08:15:37 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Garrett Cooper cc: Konstantin Belousov , Ian Lepore , Dmitry Chagin , src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r292777 - in head: lib/libc/sys sys/kern In-Reply-To: <2CA74F95-00A0-4453-847E-0C6C59B57021@gmail.com> Message-ID: <20151229070443.X864@besplex.bde.org> References: <201512271537.tBRFb7nN095297@repo.freebsd.org> <1451236237.1369.9.camel@freebsd.org> <20151228083418.B1014@besplex.bde.org> <20151228081313.GM3625@kib.kiev.ua> <20151228200006.Q2819@besplex.bde.org> <2CA74F95-00A0-4453-847E-0C6C59B57021@gmail.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=PfoC/XVd c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=JzwRw_2MAAAA:8 a=kj9zAlcOel0A:10 a=8fz06vd0j3YbmxNQynQA:9 a=CjuIK1q_8ugA:10 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Dec 2015 21:15:47 -0000 On Mon, 28 Dec 2015, Garrett Cooper wrote: > >> On Dec 28, 2015, at 02:17, Bruce Evans wrote: > > ... > >> It is not unreasonable to panic when such tests fail, just like for other >> settings of unreasonable values. Only the superuser can make them, and >> the superuser should know better than to run them on production systems. > > On a development system, this is perfectly reasonable. However, on systems in production, dying on asserts or panicking when unexpected input is encountered instead of erroring out appropriately is not ideal: it causes unnecessary downtime and can confuse others (customers, lower level admins) who are not fully aware of how UNIX and FreeBSD works (and in turn generate support calls and bug reports). This is sort of backwards. Unexpected cases by definition have no code to handle them. If you are lucky then they will be detected by an assertion or a bad pointer and cause a panic before they do further damage. Bad pointers works better for this since they cannot be turned off on production systems. Out of bounds input that is expected can be handled, but the handling can still reasonably be to panic. For example, add assertions at the lowest level that values are within bounds for the BCD array. This "handles" the bad input that is "expected" from buggy upper layers. Panics for expected cases are easier to avoid (or cause) than for unexpected cases. The super user should avoid them. Malicious users should try to caus them. But when the syscall that causes them is privileged, the malicious users can't get far. Another easy way to trigger the panic is: - abuse the adjkerntz sysctl to set a huge negative offset. utc_offset() is normally small, so it can only produce negative times from positive times in the Western hemisphere for times near the Epoch. The adjkerntz offset is added in utc_offset() so it can reach 68 years back from the current time, i.e., to 1947. The adjkerntz sysctl, like most sysctls, is correctly implemented with no bounds checking. Callers are trusted to know more about the correct bounds than the kernel. A not so way way to trigger the panic is: - set the time in the BIOS to before the Epoch if the BIOS supports that. Say 1969/01/01. - set this time in the kernel by booting if you can do that. On x86, this requires configuring with USE_RTC_CENTURY to prevent 1969 being interpreted as 2069. You now have a negative time. - find or create an ntp server that supports times before the Epoch, and set its time to 1969/01/01 - wait to sync with the ntp server with the fake time. The dubious periodic refresh of the TODR when the time is synced with ntp is not even an option and the default period is 1800 seconds. Also wait for the refresh. resettodr() is then called with a negative time. ntpd normally uses microadjustments so it is not affected by restrictions in settime(). I don't know of any other way of trying to write back the current time, and ntpd with a non-fake time doesn't do it because 1969 can only be in sync with a fake time. The periodic refresh is dubious because at least on x86 the RTC reading and setting code is sloppy and has an error of about 1 second each, and races. So setting the RTC more accurately than 1-2 seconds is worse than useless (it rarely helps, and may lose to races). It can be kept that accurate by setting it much less often than twice per hour, except for the initial setting after booting which is best done by ntpdate. Everything is best handled in userland. adjkerntz(8) handles more complicated things, and the adjkerntz sysctl can be used at any time for its side effect of calling resettodr(). The badly named machdep.disable_rtc_set sysctl still exists and is still used by adjkerntz(8) to make resettodr() do nothing. This is normally enabled, but adjkerntz(8) disables it transiently to avoid setting the RTC too often. This could be disabled more permantly to stop buggy things like settime() and the ntpd refresh ever setting the RTC. IIRC, adjkerntz(8) is fairly careful with this sysctl and restores it to its previous state after using it. Bruce