zap_modalias_env() wrongly calculates size of memory block to move, so will cause OOB memory access issue if variable MODALIAS is not the last one within its @env parameter, fixed by correcting size to memmove.
Fixes: 9b3fa47d4a76 ("kobject: fix suppressing modalias in uevents delivered over netlink") Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com --- V1 -> V2: Correct commit messages and add inline comments
V1 discussion link: https://lore.kernel.org/lkml/0b916393-eb39-4467-9c99-ac1bc9746512@quicinc.co...
lib/kobject_uevent.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 03b427e2707e..f22366be020c 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -433,8 +433,23 @@ static void zap_modalias_env(struct kobj_uevent_env *env) len = strlen(env->envp[i]) + 1;
if (i != env->envp_idx - 1) { + /* @env->envp[] contains pointers to @env->buf[] + * with @env->buflen elements, and we want to + * remove variable MODALIAS pointed by + * @env->envp[i] with length @len as shown below: + * + * 0 @env->buf[] @env->buflen + * ---------------------------------------- + * ^ ^ ^ + * |-> @len <-| target block | + * @env->envp[i] @env->envp[i+1] + * + * so the "target block" indicated above is moved + * backward by @len, and its right size is + * (@env->buf + @env->buflen - @env->envp[i + 1]). + */ memmove(env->envp[i], env->envp[i + 1], - env->buflen - len); + env->buf + env->buflen - env->envp[i + 1]);
for (j = i; j < env->envp_idx - 1; j++) env->envp[j] = env->envp[j + 1] - len;