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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230727152020.3633009-1-chengming.zhou@linux.dev>
Date:   Thu, 27 Jul 2023 23:20:18 +0800
From:   chengming.zhou@...ux.dev
To:     axboe@...nel.dk, osandov@...com, ming.lei@...hat.com,
        kbusch@...nel.org, krisman@...e.de
Cc:     linux-block@...r.kernel.org, linux-kernel@...r.kernel.org,
        zhouchengming@...edance.com
Subject: [PATCH v2 1/3] sbitmap: fix hint wrap in the failure case

From: Chengming Zhou <zhouchengming@...edance.com>

```
hint = nr + 1;
if (hint >= depth - 1)
	hint = 0;
```

Now we wrap the hint to 0 in the failure case, but has two problems:
1. hint == depth - 1, is actually an available offset hint, in which
   case we shouldn't wrap hint to 0.
2. In the strict round_robin non-wrap case, we shouldn't wrap at all.

```
wrap = wrap && hint;
```

We only need to check wrap based on the original hint ( > 0), don't need
to recheck the new hint which maybe updated in the failure case, which
may cause second wrap. We set wrap to false after we wrap once to avoid
repeated wrap, which is clearer than rechecking the hint.

Signed-off-by: Chengming Zhou <zhouchengming@...edance.com>
---
 lib/sbitmap.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/sbitmap.c b/lib/sbitmap.c
index d0a5081dfd12..ac4027884765 100644
--- a/lib/sbitmap.c
+++ b/lib/sbitmap.c
@@ -149,7 +149,8 @@ static int __sbitmap_get_word(unsigned long *word, unsigned long depth,
 			 * offset to 0 in a failure case, so start from 0 to
 			 * exhaust the map.
 			 */
-			if (hint && wrap) {
+			if (wrap) {
+				wrap = false;
 				hint = 0;
 				continue;
 			}
@@ -160,8 +161,14 @@ static int __sbitmap_get_word(unsigned long *word, unsigned long depth,
 			break;
 
 		hint = nr + 1;
-		if (hint >= depth - 1)
-			hint = 0;
+		if (unlikely(hint >= depth)) {
+			if (wrap) {
+				wrap = false;
+				hint = 0;
+				continue;
+			}
+			return -1;
+		}
 	}
 
 	return nr;
-- 
2.41.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ