lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20190813061634.5372-1-hslester96@gmail.com>
Date:   Tue, 13 Aug 2019 14:16:34 +0800
From:   Chuhong Yuan <hslester96@...il.com>
To:     unlisted-recipients:; (no To-header on input)
Cc:     Philipp Reisner <philipp.reisner@...bit.com>,
        Lars Ellenberg <lars.ellenberg@...bit.com>,
        Jens Axboe <axboe@...nel.dk>, drbd-dev@...ts.linbit.com,
        linux-block@...r.kernel.org, linux-kernel@...r.kernel.org,
        Chuhong Yuan <hslester96@...il.com>
Subject: [PATCH v2 1/3] drbd: Use refcount_t for refcount

Reference counters are preferred to use refcount_t instead of
atomic_t.
This is because the implementation of refcount_t can prevent
overflows and detect possible use-after-free.
So convert atomic_t ref counters to refcount_t.

Signed-off-by: Chuhong Yuan <hslester96@...il.com>
---
 drivers/block/drbd/drbd_int.h  |  3 ++-
 drivers/block/drbd/drbd_main.c |  4 ++--
 drivers/block/drbd/drbd_req.c  | 16 ++++++++--------
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ddbf56014c51..d5167a7a87db 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -30,6 +30,7 @@
 #include <linux/genhd.h>
 #include <linux/idr.h>
 #include <linux/dynamic_debug.h>
+#include <linux/refcount.h>
 #include <net/tcp.h>
 #include <linux/lru_cache.h>
 #include <linux/prefetch.h>
@@ -354,7 +355,7 @@ struct drbd_request {
 
 
 	/* once it hits 0, we may complete the master_bio */
-	atomic_t completion_ref;
+	refcount_t completion_ref;
 	/* once it hits 0, we may destroy this drbd_request object */
 	struct kref kref;
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9bd4ddd12b25..37746708ee84 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2295,14 +2295,14 @@ static void do_retry(struct work_struct *ws)
 		bool expected;
 
 		expected =
-			expect(atomic_read(&req->completion_ref) == 0) &&
+			expect(refcount_read(&req->completion_ref) == 0) &&
 			expect(req->rq_state & RQ_POSTPONED) &&
 			expect((req->rq_state & RQ_LOCAL_PENDING) == 0 ||
 				(req->rq_state & RQ_LOCAL_ABORTED) != 0);
 
 		if (!expected)
 			drbd_err(device, "req=%p completion_ref=%d rq_state=%x\n",
-				req, atomic_read(&req->completion_ref),
+				req, refcount_read(&req->completion_ref),
 				req->rq_state);
 
 		/* We still need to put one kref associated with the
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index f86cea4c0f8d..cb5d573e7ea2 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -69,7 +69,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
 	INIT_LIST_HEAD(&req->req_pending_local);
 
 	/* one reference to be put by __drbd_make_request */
-	atomic_set(&req->completion_ref, 1);
+	refcount_set(&req->completion_ref, 1);
 	/* one kref as long as completion_ref > 0 */
 	kref_init(&req->kref);
 	return req;
@@ -95,11 +95,11 @@ void drbd_req_destroy(struct kref *kref)
 	const unsigned s = req->rq_state;
 
 	if ((req->master_bio && !(s & RQ_POSTPONED)) ||
-		atomic_read(&req->completion_ref) ||
+		refcount_read(&req->completion_ref) ||
 		(s & RQ_LOCAL_PENDING) ||
 		((s & RQ_NET_MASK) && !(s & RQ_NET_DONE))) {
 		drbd_err(device, "drbd_req_destroy: Logic BUG rq_state = 0x%x, completion_ref = %d\n",
-				s, atomic_read(&req->completion_ref));
+				s, refcount_read(&req->completion_ref));
 		return;
 	}
 
@@ -315,7 +315,7 @@ static void drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and
 	if (!put)
 		return;
 
-	if (!atomic_sub_and_test(put, &req->completion_ref))
+	if (!refcount_sub_and_test(put, &req->completion_ref))
 		return;
 
 	drbd_req_complete(req, m);
@@ -440,15 +440,15 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
 	kref_get(&req->kref);
 
 	if (!(s & RQ_LOCAL_PENDING) && (set & RQ_LOCAL_PENDING))
-		atomic_inc(&req->completion_ref);
+		refcount_inc(&req->completion_ref);
 
 	if (!(s & RQ_NET_PENDING) && (set & RQ_NET_PENDING)) {
 		inc_ap_pending(device);
-		atomic_inc(&req->completion_ref);
+		refcount_inc(&req->completion_ref);
 	}
 
 	if (!(s & RQ_NET_QUEUED) && (set & RQ_NET_QUEUED)) {
-		atomic_inc(&req->completion_ref);
+		refcount_inc(&req->completion_ref);
 		set_if_null_req_next(peer_device, req);
 	}
 
@@ -466,7 +466,7 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
 	}
 
 	if (!(s & RQ_COMPLETION_SUSP) && (set & RQ_COMPLETION_SUSP))
-		atomic_inc(&req->completion_ref);
+		refcount_inc(&req->completion_ref);
 
 	/* progress: put references */
 
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ