From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753544AbdKQAKh (ORCPT ); Thu, 16 Nov 2017 19:10:37 -0500 Received: from mail-io0-f194.google.com ([209.85.223.194]:42395 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753507AbdKQAK3 (ORCPT ); Thu, 16 Nov 2017 19:10:29 -0500 X-Google-Smtp-Source: AGs4zMbWt7wWDVqpBGY38+jHzmIW27zmSde75jTgLgHCNgxx3BDRBJklpqiDdkSKPpFoS75wmJ2gcgpRpuaAvrJiSsI= MIME-Version: 1.0 In-Reply-To: <1510754620-27088-16-git-send-email-elena.reshetova@intel.com> References: <1510754620-27088-1-git-send-email-elena.reshetova@intel.com> <1510754620-27088-16-git-send-email-elena.reshetova@intel.com> From: Kees Cook Date: Thu, 16 Nov 2017 16:10:27 -0800 X-Google-Sender-Auth: VW9wwnskXze7w-8SiLbFJcPjGwo Message-ID: Subject: Re: [PATCH 15/16] kcov: convert kcov.refcount to refcount_t To: Andrew Morton , Elena Reshetova Cc: Ingo Molnar , LKML , "linux-fsdevel@vger.kernel.org" , Peter Zijlstra , Greg KH , Al Viro , Tejun Heo , Johannes Weiner , Li Zefan , Arnaldo Carvalho de Melo , Alexander Shishkin , Eric Paris , Arnd Bergmann , Andy Lutomirski , Thomas Gleixner , Darren Hart , "Eric W. Biederman" , Linux-MM , Jens Axboe , Dmitry Vyukov Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Nov 15, 2017 at 6:03 AM, Elena Reshetova wrote: > atomic_t variables are currently used to implement reference > counters with the following properties: > - counter is initialized to 1 using atomic_set() > - a resource is freed upon counter reaching zero > - once counter reaches zero, its further > increments aren't allowed > - counter schema uses basic atomic operations > (set, inc, inc_not_zero, dec_and_test, etc.) > > Such atomic variables should be converted to a newly provided > refcount_t type and API that prevents accidental counter overflows > and underflows. This is important since overflows and underflows > can lead to use-after-free situation and be exploitable. > > The variable kcov.refcount is used as pure reference counter. > Convert it to refcount_t and fix up the operations. > > **Important note for maintainers: > > Some functions from refcount_t API defined in lib/refcount.c > have different memory ordering guarantees than their atomic > counterparts. > The full comparison can be seen in > https://lkml.org/lkml/2017/11/15/57 and it is hopefully soon > in state to be merged to the documentation tree. > Normally the differences should not matter since refcount_t provides > enough guarantees to satisfy the refcounting use cases, but in > some rare cases it might matter. > Please double check that you don't have some undocumented > memory guarantees for this variable usage. > > For the kcov.refcount it might make a difference > in following places: > - kcov_put(): decrement in refcount_dec_and_test() only > provides RELEASE ordering and control dependency on success > vs. fully ordered atomic counterpart This also looks correct to me. Andrew, you appear to be the person for kcov changes. :) Acked-by: Kees Cook -Kees > > Suggested-by: Kees Cook > Reviewed-by: David Windsor > Reviewed-by: Hans Liljestrand > Signed-off-by: Elena Reshetova > --- > kernel/kcov.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/kernel/kcov.c b/kernel/kcov.c > index 15f33fa..343288c 100644 > --- a/kernel/kcov.c > +++ b/kernel/kcov.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > #include > > /* Number of 64-bit words written per one comparison: */ > @@ -44,7 +45,7 @@ struct kcov { > * - opened file descriptor > * - task with enabled coverage (we can't unwire it from another task) > */ > - atomic_t refcount; > + refcount_t refcount; > /* The lock protects mode, size, area and t. */ > spinlock_t lock; > enum kcov_mode mode; > @@ -228,12 +229,12 @@ EXPORT_SYMBOL(__sanitizer_cov_trace_switch); > > static void kcov_get(struct kcov *kcov) > { > - atomic_inc(&kcov->refcount); > + refcount_inc(&kcov->refcount); > } > > static void kcov_put(struct kcov *kcov) > { > - if (atomic_dec_and_test(&kcov->refcount)) { > + if (refcount_dec_and_test(&kcov->refcount)) { > vfree(kcov->area); > kfree(kcov); > } > @@ -311,7 +312,7 @@ static int kcov_open(struct inode *inode, struct file *filep) > if (!kcov) > return -ENOMEM; > kcov->mode = KCOV_MODE_DISABLED; > - atomic_set(&kcov->refcount, 1); > + refcount_set(&kcov->refcount, 1); > spin_lock_init(&kcov->lock); > filep->private_data = kcov; > return nonseekable_open(inode, filep); > -- > 2.7.4 > -- Kees Cook Pixel Security From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: MIME-Version: 1.0 In-Reply-To: <1510754620-27088-16-git-send-email-elena.reshetova@intel.com> References: <1510754620-27088-1-git-send-email-elena.reshetova@intel.com> <1510754620-27088-16-git-send-email-elena.reshetova@intel.com> From: Kees Cook Date: Thu, 16 Nov 2017 16:10:27 -0800 Message-ID: Subject: Re: [PATCH 15/16] kcov: convert kcov.refcount to refcount_t To: Andrew Morton , Elena Reshetova Cc: Ingo Molnar , LKML , "linux-fsdevel@vger.kernel.org" , Peter Zijlstra , Greg KH , Al Viro , Tejun Heo , Johannes Weiner , Li Zefan , Arnaldo Carvalho de Melo , Alexander Shishkin , Eric Paris , Arnd Bergmann , Andy Lutomirski , Thomas Gleixner , Darren Hart , "Eric W. Biederman" , Linux-MM , Jens Axboe , Dmitry Vyukov Content-Type: text/plain; charset="UTF-8" Sender: owner-linux-mm@kvack.org List-ID: On Wed, Nov 15, 2017 at 6:03 AM, Elena Reshetova wrote: > atomic_t variables are currently used to implement reference > counters with the following properties: > - counter is initialized to 1 using atomic_set() > - a resource is freed upon counter reaching zero > - once counter reaches zero, its further > increments aren't allowed > - counter schema uses basic atomic operations > (set, inc, inc_not_zero, dec_and_test, etc.) > > Such atomic variables should be converted to a newly provided > refcount_t type and API that prevents accidental counter overflows > and underflows. This is important since overflows and underflows > can lead to use-after-free situation and be exploitable. > > The variable kcov.refcount is used as pure reference counter. > Convert it to refcount_t and fix up the operations. > > **Important note for maintainers: > > Some functions from refcount_t API defined in lib/refcount.c > have different memory ordering guarantees than their atomic > counterparts. > The full comparison can be seen in > https://lkml.org/lkml/2017/11/15/57 and it is hopefully soon > in state to be merged to the documentation tree. > Normally the differences should not matter since refcount_t provides > enough guarantees to satisfy the refcounting use cases, but in > some rare cases it might matter. > Please double check that you don't have some undocumented > memory guarantees for this variable usage. > > For the kcov.refcount it might make a difference > in following places: > - kcov_put(): decrement in refcount_dec_and_test() only > provides RELEASE ordering and control dependency on success > vs. fully ordered atomic counterpart This also looks correct to me. Andrew, you appear to be the person for kcov changes. :) Acked-by: Kees Cook -Kees > > Suggested-by: Kees Cook > Reviewed-by: David Windsor > Reviewed-by: Hans Liljestrand > Signed-off-by: Elena Reshetova > --- > kernel/kcov.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/kernel/kcov.c b/kernel/kcov.c > index 15f33fa..343288c 100644 > --- a/kernel/kcov.c > +++ b/kernel/kcov.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > #include > > /* Number of 64-bit words written per one comparison: */ > @@ -44,7 +45,7 @@ struct kcov { > * - opened file descriptor > * - task with enabled coverage (we can't unwire it from another task) > */ > - atomic_t refcount; > + refcount_t refcount; > /* The lock protects mode, size, area and t. */ > spinlock_t lock; > enum kcov_mode mode; > @@ -228,12 +229,12 @@ EXPORT_SYMBOL(__sanitizer_cov_trace_switch); > > static void kcov_get(struct kcov *kcov) > { > - atomic_inc(&kcov->refcount); > + refcount_inc(&kcov->refcount); > } > > static void kcov_put(struct kcov *kcov) > { > - if (atomic_dec_and_test(&kcov->refcount)) { > + if (refcount_dec_and_test(&kcov->refcount)) { > vfree(kcov->area); > kfree(kcov); > } > @@ -311,7 +312,7 @@ static int kcov_open(struct inode *inode, struct file *filep) > if (!kcov) > return -ENOMEM; > kcov->mode = KCOV_MODE_DISABLED; > - atomic_set(&kcov->refcount, 1); > + refcount_set(&kcov->refcount, 1); > spin_lock_init(&kcov->lock); > filep->private_data = kcov; > return nonseekable_open(inode, filep); > -- > 2.7.4 > -- Kees Cook Pixel 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