From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751837AbdJ3M5k (ORCPT ); Mon, 30 Oct 2017 08:57:40 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:48953 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751251AbdJ3M5h (ORCPT ); Mon, 30 Oct 2017 08:57:37 -0400 X-Google-Smtp-Source: ABhQp+RVQPSl7xyWe3fwXYY19/Q154Pv7zuaxbD+XTCkEi+q7fjmHC7IYH4TaKQHyzfBJsR/F1iCVw== From: Ryusuke Konishi To: Andrew Morton Cc: LKML , linux-nilfs , Ryusuke Konishi , Elena Reshetova Subject: [PATCH 2/4] fs, nilfs: convert nilfs_root.count from atomic_t to refcount_t Date: Mon, 30 Oct 2017 21:52:13 +0900 Message-Id: <1509367935-3086-3-git-send-email-konishi.ryusuke@lab.ntt.co.jp> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1509367935-3086-1-git-send-email-konishi.ryusuke@lab.ntt.co.jp> References: <1509367935-3086-1-git-send-email-konishi.ryusuke@lab.ntt.co.jp> X-Dispatcher: imput version 20110525(IM151) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Elena Reshetova 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 nilfs_root.count is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by: Kees Cook Reviewed-by: David Windsor Reviewed-by: Hans Liljestrand Signed-off-by: Elena Reshetova Signed-off-by: Ryusuke Konishi --- fs/nilfs2/the_nilfs.c | 8 ++++---- fs/nilfs2/the_nilfs.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 2dd75bf..afebb50 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -737,7 +737,7 @@ struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno) } else if (cno > root->cno) { n = n->rb_right; } else { - atomic_inc(&root->count); + refcount_inc(&root->count); spin_unlock(&nilfs->ns_cptree_lock); return root; } @@ -776,7 +776,7 @@ struct nilfs_root * } else if (cno > root->cno) { p = &(*p)->rb_right; } else { - atomic_inc(&root->count); + refcount_inc(&root->count); spin_unlock(&nilfs->ns_cptree_lock); kfree(new); return root; @@ -786,7 +786,7 @@ struct nilfs_root * new->cno = cno; new->ifile = NULL; new->nilfs = nilfs; - atomic_set(&new->count, 1); + refcount_set(&new->count, 1); atomic64_set(&new->inodes_count, 0); atomic64_set(&new->blocks_count, 0); @@ -806,7 +806,7 @@ struct nilfs_root * void nilfs_put_root(struct nilfs_root *root) { - if (atomic_dec_and_test(&root->count)) { + if (refcount_dec_and_test(&root->count)) { struct the_nilfs *nilfs = root->nilfs; nilfs_sysfs_delete_snapshot_group(root); diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index b305c6f..883d732 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h @@ -27,6 +27,7 @@ #include #include #include +#include struct nilfs_sc_info; struct nilfs_sysfs_dev_subgroups; @@ -246,7 +247,7 @@ struct nilfs_root { __u64 cno; struct rb_node rb_node; - atomic_t count; + refcount_t count; struct the_nilfs *nilfs; struct inode *ifile; @@ -299,7 +300,7 @@ struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs, static inline void nilfs_get_root(struct nilfs_root *root) { - atomic_inc(&root->count); + refcount_inc(&root->count); } static inline int nilfs_valid_fs(struct the_nilfs *nilfs) -- 1.8.3.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ryusuke Konishi Subject: [PATCH 2/4] fs, nilfs: convert nilfs_root.count from atomic_t to refcount_t Date: Mon, 30 Oct 2017 21:52:13 +0900 Message-ID: <1509367935-3086-3-git-send-email-konishi.ryusuke@lab.ntt.co.jp> References: <1509367935-3086-1-git-send-email-konishi.ryusuke@lab.ntt.co.jp> Return-path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :lines; bh=w69jQb7g5c7zz0+CcrdCmGCfEMVTHefd/xk69UljQFI=; b=EFCRTY5Axylip0/Xb1/9j0qV0+0LKShVc3aSu1cdVAMxEVrsfY4zjaTqWrEGYdrfKM wKku70JTWVFmgPcJKq+zzR3Yej9VFCH+IS9UDyMzgh2wVry0BMn9WW5X8C9mXcdOZof0 iktcMNWJy1bd/l2wsW1ugCZkXlXOURw+Luzz0TtHM2FA1zrUpi0/cm3Fdi6V4qdPBcSJ 9YXU9o99eIkYLp7Ye4Qw00ciOtFLUiX1PZcgLR2jcNCCC8JwW38RvxPNSmd+VlcPf1b6 /xh4WqjllpVyzihEhLzR+wxjv1uJy40CHa7JUnp11+l98iBulLmoBB243iE36CJ8Rsnz 7sqA== In-Reply-To: <1509367935-3086-1-git-send-email-konishi.ryusuke-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org> Sender: linux-nilfs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: Andrew Morton Cc: LKML , linux-nilfs , Ryusuke Konishi , Elena Reshetova From: Elena Reshetova 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 nilfs_root.count is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by: Kees Cook Reviewed-by: David Windsor Reviewed-by: Hans Liljestrand Signed-off-by: Elena Reshetova Signed-off-by: Ryusuke Konishi --- fs/nilfs2/the_nilfs.c | 8 ++++---- fs/nilfs2/the_nilfs.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 2dd75bf..afebb50 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -737,7 +737,7 @@ struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno) } else if (cno > root->cno) { n = n->rb_right; } else { - atomic_inc(&root->count); + refcount_inc(&root->count); spin_unlock(&nilfs->ns_cptree_lock); return root; } @@ -776,7 +776,7 @@ struct nilfs_root * } else if (cno > root->cno) { p = &(*p)->rb_right; } else { - atomic_inc(&root->count); + refcount_inc(&root->count); spin_unlock(&nilfs->ns_cptree_lock); kfree(new); return root; @@ -786,7 +786,7 @@ struct nilfs_root * new->cno = cno; new->ifile = NULL; new->nilfs = nilfs; - atomic_set(&new->count, 1); + refcount_set(&new->count, 1); atomic64_set(&new->inodes_count, 0); atomic64_set(&new->blocks_count, 0); @@ -806,7 +806,7 @@ struct nilfs_root * void nilfs_put_root(struct nilfs_root *root) { - if (atomic_dec_and_test(&root->count)) { + if (refcount_dec_and_test(&root->count)) { struct the_nilfs *nilfs = root->nilfs; nilfs_sysfs_delete_snapshot_group(root); diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index b305c6f..883d732 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h @@ -27,6 +27,7 @@ #include #include #include +#include struct nilfs_sc_info; struct nilfs_sysfs_dev_subgroups; @@ -246,7 +247,7 @@ struct nilfs_root { __u64 cno; struct rb_node rb_node; - atomic_t count; + refcount_t count; struct the_nilfs *nilfs; struct inode *ifile; @@ -299,7 +300,7 @@ struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs, static inline void nilfs_get_root(struct nilfs_root *root) { - atomic_inc(&root->count); + refcount_inc(&root->count); } static inline int nilfs_valid_fs(struct the_nilfs *nilfs) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html