[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <365eddac-2d20-4f8d-072a-f868c4398a9e@huawei.com>
Date: Wed, 19 Apr 2023 16:41:38 +0800
From: Xia Fukun <xiafukun@...wei.com>
To: Greg KH <gregkh@...uxfoundation.org>
CC: <prajnoha@...hat.com>, <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v3] kobject: Fix global-out-of-bounds in
kobject_action_type()
On 2023/3/9 20:40, Greg KH wrote:>>
>> Modify the judgment logic in line 87. If the length of the string
>> kobject_actions[action] is greater than count_first(e.g. buf is "off",
>> count is 3), continue the loop.
>> Otherwise, the match is considered successful.
>>
>> This change means that our test case will be successfully parsed as an
>> offline event and no out-of-bounds access error will occur.
>
> Yes, but what other test cases did you run on this to verify it works?
> Given that your previous version broke previously working inputs I need
> a lot of validation and proof that this change will also not break
> anything.
>
>
> I'm sorry, but as I said before, I'm still not convinced that this is
> correct. Why does this solve the problem? Shouldn't the length check
> come before we try to compare the string so that strncmp() doesn't have
> to give a false-positive if the string is too small?
>
The string "buf" needs to be compared in sequence with the string array
defined below to confirm a match with one of them, and the length of these
strings ranges from 3 to 7. Checking the length of "buf" in advance still
cannot avoid the situation mentioned in this patch(e.g. buf is "off",count is 3)
static const char *kobject_actions[] = {
[KOBJ_ADD] = "add",
[KOBJ_REMOVE] = "remove",
[KOBJ_CHANGE] = "change",
[KOBJ_MOVE] = "move",
[KOBJ_ONLINE] = "online",
[KOBJ_OFFLINE] = "offline",
[KOBJ_BIND] = "bind",
[KOBJ_UNBIND] = "unbind",
};
> And really, this whole function is very hard to follow, is there any
> chance you can refactor it to be more obviously correct and readable?
> What about taking advantage of the well-tested string functions we
> already have for parsing sysfs inputs, like sysfs_match_string()?
>
As for using sysfs_match_string() to refactor this code,
do you think whether the following modification methods are suitable and clear?
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 7c44b7ae4c5c..5fce99c3cb8b 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -66,7 +66,7 @@ static int kobject_action_type(const char *buf, size_t count,
enum kobject_action action;
size_t count_first;
const char *args_start;
- int ret = -EINVAL;
+ int i, ret = -EINVAL;
if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
count--;
@@ -81,17 +81,16 @@ static int kobject_action_type(const char *buf, size_t count,
} else
} else
count_first = count;
- for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {
- if (strncmp(kobject_actions[action], buf, count_first) != 0)
- continue;
- if (kobject_actions[action][count_first] != '\0')
- continue;
- if (args)
- *args = args_start;
- *type = action;
- ret = 0;
- break;
- }
+ /* Use sysfs_match_string() to replace the fragile and convoluted loop */
+ i = sysfs_match_string(kobject_actions, buf);
+ if (i < 0)
+ return ret;
+ action = kobject_action(i);
+ if (args)
+ *args = args_start;
+ *type = action;
+ ret = 0;
+
out:
return ret;
}
> thanks,
>
> greg k-h
Also, I apologize for my previous top-posting behavior.
Considering that I am a novice in the kernel field,
I hope you can forgive me a lot.
Powered by blists - more mailing lists