From patchwork Thu Mar 2 10:43:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Reshetova, Elena" X-Patchwork-Id: 9599977 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F2B5460414 for ; Thu, 2 Mar 2017 10:47:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2A2E20144 for ; Thu, 2 Mar 2017 10:47:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C7302285A9; Thu, 2 Mar 2017 10:47:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DEE320144 for ; Thu, 2 Mar 2017 10:47:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751923AbdCBKop (ORCPT ); Thu, 2 Mar 2017 05:44:45 -0500 Received: from mga05.intel.com ([192.55.52.43]:16316 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751113AbdCBKoN (ORCPT ); Thu, 2 Mar 2017 05:44:13 -0500 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP; 02 Mar 2017 02:44:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,230,1484035200"; d="scan'208";a="231414837" Received: from bheise-mobl.ger.corp.intel.com (HELO elena-ThinkPad-X230.ger.corp.intel.com) ([10.249.41.240]) by fmsmga004.fm.intel.com with ESMTP; 02 Mar 2017 02:43:58 -0800 From: Elena Reshetova To: linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-nilfs@vger.kernel.org, linux-cachefs@redhat.com, linux-cifs@vger.kernel.org, peterz@infradead.org, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, dhowells@redhat.com, sfrench@samba.org, eparis@parisplace.org, konishi.ryusuke@lab.ntt.co.jp, john@johnmccutchan.com, rlove@rlove.org, paul@paul-moore.com, Elena Reshetova , Hans Liljestrand , Kees Cook , David Windsor Subject: [PATCH 07/10] fs, fscache: convert fscache_operation.usage from atomic_t to refcount_t Date: Thu, 2 Mar 2017 12:43:14 +0200 Message-Id: <1488451397-3365-8-git-send-email-elena.reshetova@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488451397-3365-1-git-send-email-elena.reshetova@intel.com> References: <1488451397-3365-1-git-send-email-elena.reshetova@intel.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by: Elena Reshetova Signed-off-by: Hans Liljestrand Signed-off-by: Kees Cook Signed-off-by: David Windsor --- fs/cachefiles/rdwr.c | 2 +- fs/fscache/operation.c | 38 +++++++++++++++++++------------------- fs/fscache/page.c | 2 +- include/linux/fscache-cache.h | 4 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index afbdc41..c987de6 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -692,7 +692,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, struct cachefiles_cache, cache); _enter("{OBJ%x,%d},,%d,,", - object->fscache.debug_id, atomic_read(&op->op.usage), + object->fscache.debug_id, refcount_read(&op->op.usage), *nr_pages); if (!object->backer) diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index de67745..eb84c95 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c @@ -38,7 +38,7 @@ void fscache_operation_init(struct fscache_operation *op, fscache_operation_release_t release) { INIT_WORK(&op->work, fscache_op_work_func); - atomic_set(&op->usage, 1); + refcount_set(&op->usage, 1); op->state = FSCACHE_OP_ST_INITIALISED; op->debug_id = atomic_inc_return(&fscache_op_debug_id); op->processor = processor; @@ -60,19 +60,19 @@ EXPORT_SYMBOL(fscache_operation_init); void fscache_enqueue_operation(struct fscache_operation *op) { _enter("{OBJ%x OP%x,%u}", - op->object->debug_id, op->debug_id, atomic_read(&op->usage)); + op->object->debug_id, op->debug_id, refcount_read(&op->usage)); ASSERT(list_empty(&op->pend_link)); ASSERT(op->processor != NULL); ASSERT(fscache_object_is_available(op->object)); - ASSERTCMP(atomic_read(&op->usage), >, 0); + ASSERTCMP(refcount_read(&op->usage), >, 0); ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS); fscache_stat(&fscache_n_op_enqueue); switch (op->flags & FSCACHE_OP_TYPE) { case FSCACHE_OP_ASYNC: _debug("queue async"); - atomic_inc(&op->usage); + refcount_inc(&op->usage); if (!queue_work(fscache_op_wq, &op->work)) fscache_put_operation(op); break; @@ -156,7 +156,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object, _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); - ASSERTCMP(atomic_read(&op->usage), >, 0); + ASSERTCMP(refcount_read(&op->usage), >, 0); spin_lock(&object->lock); ASSERTCMP(object->n_ops, >=, object->n_in_progress); @@ -183,11 +183,11 @@ int fscache_submit_exclusive_op(struct fscache_object *object, object->n_exclusive++; /* reads and writes must wait */ if (object->n_in_progress > 0) { - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); } else if (!list_empty(&object->pending_ops)) { - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); fscache_start_operations(object); @@ -203,7 +203,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object, op->object = object; object->n_ops++; object->n_exclusive++; /* reads and writes must wait */ - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); ret = 0; @@ -238,10 +238,10 @@ int fscache_submit_op(struct fscache_object *object, int ret; _enter("{OBJ%x OP%x},{%u}", - object->debug_id, op->debug_id, atomic_read(&op->usage)); + object->debug_id, op->debug_id, refcount_read(&op->usage)); ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); - ASSERTCMP(atomic_read(&op->usage), >, 0); + ASSERTCMP(refcount_read(&op->usage), >, 0); spin_lock(&object->lock); ASSERTCMP(object->n_ops, >=, object->n_in_progress); @@ -267,11 +267,11 @@ int fscache_submit_op(struct fscache_object *object, object->n_ops++; if (object->n_exclusive > 0) { - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); } else if (!list_empty(&object->pending_ops)) { - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); fscache_start_operations(object); @@ -283,7 +283,7 @@ int fscache_submit_op(struct fscache_object *object, } else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) { op->object = object; object->n_ops++; - atomic_inc(&op->usage); + refcount_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); ret = 0; @@ -359,7 +359,7 @@ int fscache_cancel_op(struct fscache_operation *op, ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING); ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED); - ASSERTCMP(atomic_read(&op->usage), >, 0); + ASSERTCMP(refcount_read(&op->usage), >, 0); spin_lock(&object->lock); @@ -481,11 +481,11 @@ void fscache_put_operation(struct fscache_operation *op) struct fscache_cache *cache; _enter("{OBJ%x OP%x,%d}", - op->object->debug_id, op->debug_id, atomic_read(&op->usage)); + op->object->debug_id, op->debug_id, refcount_read(&op->usage)); - ASSERTCMP(atomic_read(&op->usage), >, 0); + ASSERTCMP(refcount_read(&op->usage), >, 0); - if (!atomic_dec_and_test(&op->usage)) + if (!refcount_dec_and_test(&op->usage)) return; _debug("PUT OP"); @@ -569,7 +569,7 @@ void fscache_operation_gc(struct work_struct *work) object->debug_id, op->debug_id); fscache_stat(&fscache_n_op_gc); - ASSERTCMP(atomic_read(&op->usage), ==, 0); + ASSERTCMP(refcount_read(&op->usage), ==, 0); ASSERTCMP(op->state, ==, FSCACHE_OP_ST_DEAD); ASSERTCMP(object->n_ops, >, 0); @@ -599,7 +599,7 @@ void fscache_op_work_func(struct work_struct *work) unsigned long start; _enter("{OBJ%x OP%x,%d}", - op->object->debug_id, op->debug_id, atomic_read(&op->usage)); + op->object->debug_id, op->debug_id, refcount_read(&op->usage)); ASSERT(op->processor != NULL); start = jiffies; diff --git a/fs/fscache/page.c b/fs/fscache/page.c index c8c4f79..352393c 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -774,7 +774,7 @@ static void fscache_write_op(struct fscache_operation *_op) void *results[1]; int ret; - _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); + _enter("{OP%x,%d}", op->op.debug_id, refcount_read(&op->op.usage)); spin_lock(&object->lock); cookie = object->cookie; diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index dcec7b3..0093158 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -103,7 +103,7 @@ struct fscache_operation { #define FSCACHE_OP_KEEP_FLAGS 0x00f0 /* flags to keep when repurposing an op */ enum fscache_operation_state state; - atomic_t usage; + refcount_t usage; unsigned debug_id; /* debugging ID */ /* operation processor callback @@ -161,7 +161,7 @@ typedef int (*fscache_pages_retrieval_func_t)(struct fscache_retrieval *op, static inline struct fscache_retrieval *fscache_get_retrieval(struct fscache_retrieval *op) { - atomic_inc(&op->op.usage); + refcount_inc(&op->op.usage); return op; }