On 2022-10-24 08:19, Yang Yingliang wrote: > Inject fault while loading module, kset_register() may fail. > If it fails, the name allocated by kobject_set_name() which > is called before kset_register() is leaked, because refcount > of kobject is hold in kset_init(). "is hold" --> "was set". Also, I'd say "which must be called" instead of "is", since we cannot register kobj/kset without a name--the kobj code crashes, and we want to make this clear. IOW, a novice user may wonder where "is" it called, as opposed to learning that they "must" call it to allocate/set a name, before calling kset_register(). So, I'd say this: "If it fails, the name allocated by kobject_set_name() which must be called before a call to kset_regsiter() is leaked, since refcount of kobj was set in kset_init()." > > As a kset may be embedded in a larger structure which needs > be freed in release() function or error path in callers, we Drop "As", start with "A kset". "which needs _to_ be". Also please specify that the release is part of the ktype, like this: "A kset may be embedded in a larger structure which needs to be freed in ktype.release() or error path in callers, we ..." > can not call kset_put() in kset_register(), or it will cause > double free, so just call kfree_const() to free the name and > set it to NULL. > > With this fix, the callers don't need to care about the name > freeing and call an extra kset_put() if kset_register() fails. This is unclear because you're *missing* a verb: "and call an extra kset_put()". Please add the proper verb _between_ "and call", something like, "With this fix, the callers don't need to care about freeing the name of the kset, and _can_ call kset_put() if kset_register() fails." Choose a proper verb here: can, should, cannot, should not, etc. We can do this because you set "kset.kobj.name to NULL, and this is checked for in kobject_cleanup(). We just need to stipulate whether they should/shouldn't have to call kset_put(), or can free the kset and/or the embedding object themselves. This really depends on how we want kset_register() to behave in the future, and on user's own ktype.release implementation... > > Suggested-by: Luben Tuikov <luben.tuikov@xxxxxxx> > Signed-off-by: Yang Yingliang <yangyingliang@xxxxxxxxxx> > --- > v1 -> v2: > Free name inside of kset_register() instead of calling kset_put() > in drivers. > --- > lib/kobject.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/lib/kobject.c b/lib/kobject.c > index a0b2dbfcfa23..3409a89c81e5 100644 > --- a/lib/kobject.c > +++ b/lib/kobject.c > @@ -834,6 +834,9 @@ EXPORT_SYMBOL_GPL(kobj_sysfs_ops); > /** > * kset_register() - Initialize and add a kset. > * @k: kset. > + * > + * NOTE: On error, the kset.kobj.name allocated by() kobj_set_name() > + * which is called before kset_register() in caller need be freed. > */ > int kset_register(struct kset *k) > { > @@ -844,8 +847,11 @@ int kset_register(struct kset *k) > > kset_init(k); > err = kobject_add_internal(&k->kobj); > - if (err) > + if (err) { > + kfree_const(k->kobj.name); > + k->kobj.name = NULL; > return err; > + } This looks good. It's good you set kset.kobj.name to NULL, so that recovery/free paths don't get confused. Waiting for v3. (I guess this is no different than what we currently do in kobject_cleanup(), so I see it as safe, no-surprises implementation.) Regards, Luben