Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751890AbdF3D6O (ORCPT ); Thu, 29 Jun 2017 23:58:14 -0400 Received: from mail-it0-f52.google.com ([209.85.214.52]:38718 "EHLO mail-it0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751333AbdF3D6N (ORCPT ); Thu, 29 Jun 2017 23:58:13 -0400 MIME-Version: 1.0 In-Reply-To: References: <1496180392-98718-1-git-send-email-keescook@chromium.org> <1496180392-98718-4-git-send-email-keescook@chromium.org> <3812aec2-682f-e95c-4d61-8e7eac33cc88@huawei.com> From: Kees Cook Date: Thu, 29 Jun 2017 20:58:10 -0700 X-Google-Sender-Auth: QQoWoI-fsbKSzmgVtdlsON5rzVg Message-ID: Subject: Re: [kernel-hardening] [PATCH v5 3/3] x86/refcount: Implement fast refcount overflow protection To: Li Kun Cc: LKML , Christoph Hellwig , Peter Zijlstra , "Eric W. Biederman" , Andrew Morton , Josh Poimboeuf , PaX Team , Jann Horn , Eric Biggers , Elena Reshetova , Hans Liljestrand , David Windsor , Greg KH , Ingo Molnar , Alexey Dobriyan , "Serge E. Hallyn" , arozansk@redhat.com, Davidlohr Bueso , Manfred Spraul , "axboe@kernel.dk" , James Bottomley , "x86@kernel.org" , Ingo Molnar , Arnd Bergmann , "David S. Miller" , Rik van Riel , linux-arch , "kernel-hardening@lists.openwall.com" , "Wangkai (Morgan, Euler)" 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-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by mail.home.local id v5U3wHJ9027715 Content-Length: 2678 Lines: 69 On Thu, Jun 29, 2017 at 7:42 PM, Li Kun wrote: > > > on 2017/6/30 6:05, Kees Cook wrote: >> >> On Wed, Jun 28, 2017 at 9:13 PM, Li Kun wrote: >>> >>> 在 2017/5/31 5:39, Kees Cook 写道: >>>> >>>> +bool ex_handler_refcount(const struct exception_table_entry *fixup, >>>> + struct pt_regs *regs, int trapnr) >>>> +{ >>>> + int reset; >>>> + >>>> + /* >>>> + * If we crossed from INT_MAX to INT_MIN, the OF flag (result >>>> + * wrapped around) and the SF flag (result is negative) will be >>>> + * set. In this case, reset to INT_MAX in an attempt to leave >>>> the >>>> + * refcount usable. Otherwise, we've landed here due to >>>> producing >>>> + * a negative result from either decrementing zero or operating >>>> on >>>> + * a negative value. In this case things are badly broken, so we >>>> + * we saturate to INT_MIN / 2. >>>> + */ >>>> + if (regs->flags & (X86_EFLAGS_OF | X86_EFLAGS_SF)) >>>> + reset = INT_MAX; >>> >>> Should it be like this to indicate that the refcount is wapped from >>> INT_MAX to INT_MIN ? >>> if (regs->flags & (X86_EFLAGS_OF | X86_EFLAGS_SF) >>> == (X86_EFLAGS_OF | X86_EFLAGS_SF)) >>> >>> reset = INT_MAX; >> >> Ah yes, thanks for the catch. Yeah, that test is expecting both >> condition flags to be set. >> >> I'm still on the fence about the best way to deal with the bad states. >> I've been pondering just strictly using a saturation value (INT_MIN / >> 2), which should offer the same system state protection (except for >> the inherent resource leak), but that means there isn't really a good >> way to kill an offending process (since after saturation ALL processes >> will look like violators). It can be argued that killing the process >> doesn't actually provide any benefit since the system is still safe, >> though. > > An immature idea,can we set the count to INT_MAX/2 when we detect and kill > the offending process, > and wait to see if there will be another offender touching the fence. Er,not > very acurate,but better than > killing all the processes doing refcount_add ,i think. >>>> >>>> + else >>>> + reset = INT_MIN / 2; >>>> + *(int *)regs->cx = reset; I suppose we could kill a process if it did the wrap from INT_MAX to INT_MIN, and then ignore (though maintain saturation of) the rest. i.e. if X86_EFLAGS_OF, kill and saturate. If X86_EFLAGS_SF, saturate. I'm still curious about catching refcount_dec() (not refcount_dec_and_test()) hitting zero. -Kees -- Kees Cook Pixel Security