Re: [PATCH] md: md2: fix an incorrect NULL check on list iterator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Xiaomeng,

I'd suggest to rephrase the subject to "md: fix an incorrect NULL check in md_reload_sb".

On 3/27/22 4:01 PM, Xiaomeng Tong wrote:
The bug is here:
	if (!rdev || rdev->desc_nr != nr) {

The list iterator value 'rdev' will *always* be set and non-NULL
by rdev_for_each_rcu(), so it is incorrect to assume that the
iterator value will be NULL if the list is empty or no element
found (In fact, it will be a bogus pointer to an invalid struct
object containing the HEAD). Otherwise it will bypass the check
and lead to invalid memory access passing the check.

To fix the bug, use a new variable 'iter' as the list iterator,
while use the original variable 'pdev' as a dedicated pointer to
point to the found element.

Cc:stable@xxxxxxxxxxxxxxx
Fixes: 70bcecdb1534 ("amd-cluster: Improve md_reload_sb to be less error prone")

amd-cluster? 😉

Signed-off-by: Xiaomeng Tong<xiam0nd.tong@xxxxxxxxx>
---
  drivers/md/md.c | 10 ++++++----
  1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7476fc204172..f156678c08bc 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -9794,16 +9794,18 @@ static int read_rdev(struct mddev *mddev, struct md_rdev *rdev)
void md_reload_sb(struct mddev *mddev, int nr)
  {
-	struct md_rdev *rdev;
+	struct md_rdev *rdev = NULL, *iter;
  	int err;
/* Find the rdev */
-	rdev_for_each_rcu(rdev, mddev) {
-		if (rdev->desc_nr == nr)
+	rdev_for_each_rcu(iter, mddev) {
+		if (iter->desc_nr == nr) {
+			rdev = iter;
  			break;
+		}
  	}
- if (!rdev || rdev->desc_nr != nr) {
+	if (!rdev) {
  		pr_warn("%s: %d Could not find rdev with nr %d\n", __func__, __LINE__, nr);
  		return;
  	}

I guess we only need to check desc_nr since rdev should always be valid , and IMO the fix tag
is not necessary.

@@ -9800,7 +9800,7 @@ void md_reload_sb(struct mddev *mddev, int nr)
                        break;
        }

-       if (!rdev || rdev->desc_nr != nr) {
+       if (rdev->desc_nr != nr) {

Thanks,
Guoqing



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux