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-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230626080913.3493135-4-linan666@huaweicloud.com>
Date:   Mon, 26 Jun 2023 16:09:12 +0800
From:   linan666@...weicloud.com
To:     axboe@...nel.dk, linan122@...wei.com, vishal.l.verma@...el.com,
        dan.j.williams@...el.com, ashok_raj@...ux.intel.com
Cc:     linux-block@...r.kernel.org, linux-kernel@...r.kernel.org,
        yukuai3@...wei.com, yi.zhang@...wei.com, houtao1@...wei.com,
        yangerkun@...wei.com
Subject: [PATCH v4 3/4] block/badblocks: fix badblocks loss when badblocks combine

From: Li Nan <linan122@...wei.com>

badblocks will loss if set it as below:
  $ echo 1 1 > bad_blocks
  $ echo 3 1 > bad_blocks
  $ echo 1 4 > bad_blocks
  $ cat bad_blocks
    1 3

After the fix, in the same scenario, it will be:
  $ cat bad_blocks
    1 4

In badblocks_set(), if set a new badblocks, first find two existing
badblocks adjacent to it, named lo and hi. Then try to merge new with lo.
If merge success and there is an intersection between lo and hi, try to
combine lo and hi.

set 1 4
binary-search:
  lo: 1 1	|____|
  hi: 3 1		  |____|

merge with lo:
  lo: 1 4	|___________________|
  hi: 3 1		  |____|

combine lo and hi:
  result: 1 3	|______________|
			       | -> hi's end
			       |____| -> lost

Now, the end of combined badblocks must be hi's end. However, it should be
the larger one between lo and hi. Fix it.

Fixes: 9e0e252a048b ("badblocks: Add core badblock management code")
Signed-off-by: Li Nan <linan122@...wei.com>
---
 block/badblocks.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/block/badblocks.c b/block/badblocks.c
index 7b1ad364e85c..c1745b76d8f1 100644
--- a/block/badblocks.c
+++ b/block/badblocks.c
@@ -267,16 +267,14 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
 	if (sectors == 0 && hi < bb->count) {
 		/* we might be able to combine lo and hi */
 		/* Note: 's' is at the end of 'lo' */
-		sector_t a = BB_OFFSET(p[hi]);
-		int lolen = BB_LEN(p[lo]);
-		int hilen = BB_LEN(p[hi]);
-		int newlen = lolen + hilen - (s - a);
+		sector_t a = BB_OFFSET(p[lo]);
+		int newlen = max(s, BB_OFFSET(p[hi]) + BB_LEN(p[hi])) - a;
 
-		if (s >= a && newlen < BB_MAX_LEN) {
+		if (s >= BB_OFFSET(p[hi]) && newlen < BB_MAX_LEN) {
 			/* yes, we can combine them */
 			int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]);
 
-			p[lo] = BB_MAKE(BB_OFFSET(p[lo]), newlen, ack);
+			p[lo] = BB_MAKE(a, newlen, ack);
 			memmove(p + hi, p + hi + 1,
 				(bb->count - hi - 1) * 8);
 			bb->count--;
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ