Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751100AbdGYTLN (ORCPT ); Tue, 25 Jul 2017 15:11:13 -0400 Received: from mail-it0-f50.google.com ([209.85.214.50]:36606 "EHLO mail-it0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750771AbdGYTLK (ORCPT ); Tue, 25 Jul 2017 15:11:10 -0400 MIME-Version: 1.0 In-Reply-To: <7e7918c6-7186-47f4-4b37-2fc55db1e678@huawei.com> References: <1500921349-10803-1-git-send-email-keescook@chromium.org> <1500921349-10803-4-git-send-email-keescook@chromium.org> <7e7918c6-7186-47f4-4b37-2fc55db1e678@huawei.com> From: Kees Cook Date: Tue, 25 Jul 2017 12:11:08 -0700 X-Google-Sender-Auth: KgEY5IZjJE2knNnuYIcW9bd3lq0 Message-ID: Subject: Re: [kernel-hardening] [PATCH v8 3/3] x86/refcount: Implement fast refcount overflow protection To: Li Kun Cc: Ingo Molnar , Peter Zijlstra , Josh Poimboeuf , Christoph Hellwig , "Eric W. Biederman" , Andrew Morton , Jann Horn , Eric Biggers , Elena Reshetova , Hans Liljestrand , Greg KH , Alexey Dobriyan , "Serge E. Hallyn" , arozansk@redhat.com, Davidlohr Bueso , Manfred Spraul , "axboe@kernel.dk" , James Bottomley , "x86@kernel.org" , Arnd Bergmann , "David S. Miller" , Rik van Riel , LKML , linux-arch , "kernel-hardening@lists.openwall.com" 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: 1431 Lines: 48 On Tue, Jul 25, 2017 at 5:03 AM, Li Kun wrote: > Hi Kees, > > > on 2017/7/25 2:35, Kees Cook wrote: >> >> +static __always_inline __must_check >> +int __refcount_add_unless(refcount_t *r, int a, int u) >> +{ >> + int c, new; >> + >> + c = atomic_read(&(r->refs)); >> + do { >> + if (unlikely(c == u)) >> + break; >> + >> + asm volatile("addl %2,%0\n\t" >> + REFCOUNT_CHECK_LT_ZERO >> + : "=r" (new) >> + : "0" (c), "ir" (a), >> + [counter] "m" (r->refs.counter) >> + : "cc", "cx"); >> + >> + } while (!atomic_try_cmpxchg(&(r->refs), &c, new)); >> + >> + return c; >> +} > > here when the result LT_ZERO, you will saturate the r->refs.counter and make > the > > atomic_try_cmpxchg(&(r->refs), &c, new) bound to fail first time. > > maybe we can just saturate the value of variable "new" ? Oh, good catch! Thanks. Actually, it's even worse than that: we'll exit this function without the refcount being correctly saturated. The final result will be INT_MIN / 2 + a. It's not terrible, but I should have noticed this in testing. (There was a gap in my testing for the _not_zero() overflows, which I've fixed now...) I'll figure this out or revert to the logic I was using in v6... -Kees -- Kees Cook Pixel Security