Re: [RFC PATCH v4 3/4] livepatch: Implement replace set for scoped atomic replace
Yafang Shao <[email protected]> Tue, 4 Aug 2026 15:15:18 +0800
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.live-patching |
|---|---|
| Message-ID | <CALOAHbDmZBahx3Qsvfs5Y-qV+CvMg7FDaXoN1bj+m+EcKd04CA@mail.gmail.com> |
On Tue, Aug 4, 2026 at 3:03=E2=80=AFPM <[email protected]> wrote: > > Thank you for your contribution! Sashiko AI review found 1 potential issu= e(s) to consider: > - [Medium] Dynamically allocated `funcs` arrays are leaked on KLP_OBSOLET= ES parsing failure. > -- > > --- Patch [3]: [RFC PATCH v4 3/4] livepatch: Implement replace set for sc= oped atomic replace --- > commit d186609c1a3dbe210857d0040f657fa918504faf > Author: Yafang Shao <[email protected]> > Subject: livepatch: Implement replace set for scoped atomic replace > > This commit introduces a more flexible atomic replace model for livepatch= es > using provides and obsoletes fields. A new patch will replace any existin= g > patch with a matching provides ID or any ID listed in its obsoletes array= . > The klp-build script and init code are updated to parse and validate thes= e > new fields. > > > diff --git a/scripts/livepatch/init.c b/scripts/livepatch/init.c > > --- a/scripts/livepatch/init.c > > +++ b/scripts/livepatch/init.c > [ ... ] > > @@ -72,10 +73,73 @@ static int __init livepatch_mod_init(void) > [ ... ] > > +#ifdef KLP_OBSOLETES > > + /* > > + * Parse KLP_OBSOLETES string (format: "0,1,2" or "0" or empty) > > + * and convert to unsigned int array for patch->obsoletes > > + * > > + * Note: KLP_OBSOLETES is always defined and includes at least th= e > > + * provides ID, ensuring the patch replaces old patches with same= ID. > > + */ > > + { > > + unsigned int *obs_array; > > + unsigned int count =3D 1; > > + char *obsoletes_str; > > + char *token, *str; > > + int i =3D 0; > > + > > + for (str =3D (char *)KLP_OBSOLETES; *str; str++) { > > + if (*str =3D=3D ',') > > + count++; > > + } > > + > > + obsoletes_str =3D kstrdup(KLP_OBSOLETES, GFP_KERNEL); > > + if (!obsoletes_str) { > > + ret =3D -ENOMEM; > > + goto err_free_objs; > > + } > > + > > + obs_array =3D kmalloc_array(count, sizeof(unsigned int), = GFP_KERNEL); > > + if (!obs_array) { > > + kfree(obsoletes_str); > > + ret =3D -ENOMEM; > > + goto err_free_objs; > > + } > > + > > + str =3D obsoletes_str; > > + while ((token =3D strsep(&str, ",")) !=3D NULL) { > > + unsigned int val; > > + > > + ret =3D kstrtouint(token, 10, &val); > > + if (ret) { > > + kfree(obsoletes_str); > > + kfree(obs_array); > > + goto err_free_objs; > > + } > > + obs_array[i++] =3D val; > > + } > > [Severity: Medium] > Does this code leak the funcs arrays on error? > > Earlier in livepatch_mod_init(), the funcs arrays are dynamically allocat= ed > for each object in a loop: > > funcs =3D kzalloc(sizeof(struct klp_func) * (nr_funcs + 1), GFP_K= ERNEL); > ... > obj->funcs =3D funcs; > > If KLP_OBSOLETES parsing fails during string duplication, array allocatio= n, > or integer conversion, the error paths jump to err_free_objs. It appears > that the cleanup label only frees the objs array itself but leaves the > individual obj->funcs arrays allocated: > > err_free_objs: > kfree(objs); > err_free_patch: > kfree(patch); You are right. Furthermore, there is a pre-existing bug in the error path that should be fixed as well: --- a/scripts/livepatch/init.c +++ b/scripts/livepatch/init.c @@ -52,7 +52,7 @@ static int __init livepatch_mod_init(void) if (!funcs) { ret =3D -ENOMEM; for (int j =3D 0; j < i; j++) - kfree(objs[i].funcs); + kfree(objs[j].funcs); goto err_free_objs; } --=20 Regards Yafang