On 10/6/20 5:55 AM, Oliver O'Halloran wrote: > On Mon, Oct 5, 2020 at 3:12 PM Mahesh Salgaonkar <mah...@linux.ibm.com> wrote: >> >> Every error log reported by OPAL is exported to userspace through a sysfs >> interface and notified using kobject_uevent(). The userspace daemon >> (opal_errd) then reads the error log and acknowledges it error log is saved >> safely to disk. Once acknowledged the kernel removes the respective sysfs >> file entry causing respective resources getting released including kobject. >> >> However there are chances where user daemon may already be scanning elog >> entries while new sysfs elog entry is being created by kernel. User daemon >> may read this new entry and ack it even before kernel can notify userspace >> about it through kobject_uevent() call. If that happens then we have a >> potential race between elog_ack_store->kobject_put() and kobject_uevent >> which can lead to use-after-free issue of a kernfs object resulting into a >> kernel crash. This patch fixes this race by protecting a sysfs file >> creation/notification by holding an additional reference count on kobject >> until we safely send kobject_uevent(). >> >> Reported-by: Oliver O'Halloran <ooh...@gmail.com> >> Signed-off-by: Mahesh Salgaonkar <mah...@linux.ibm.com> >> Signed-off-by: Aneesh Kumar K.V <aneesh.ku...@linux.ibm.com> >> --- >> Change in v2: >> - Instead of mutex and use extra reference count on kobject to avoid the >> race. >> --- >> arch/powerpc/platforms/powernv/opal-elog.c | 15 +++++++++++++++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/arch/powerpc/platforms/powernv/opal-elog.c >> b/arch/powerpc/platforms/powernv/opal-elog.c >> index 62ef7ad995da..230f102e87c0 100644 >> --- a/arch/powerpc/platforms/powernv/opal-elog.c >> +++ b/arch/powerpc/platforms/powernv/opal-elog.c >> @@ -222,13 +222,28 @@ static struct elog_obj *create_elog_obj(uint64_t id, >> size_t size, uint64_t type) >> return NULL; >> } >> >> + /* >> + * As soon as sysfs file for this elog is created/activated there is >> + * chance opal_errd daemon might read and acknowledge this elog >> before >> + * kobject_uevent() is called. If that happens then we have a >> potential >> + * race between elog_ack_store->kobject_put() and kobject_uevent >> which >> + * leads to use-after-free issue of a kernfs object resulting into >> + * kernel crash. To avoid this race take an additional reference >> count >> + * on kobject until we safely send kobject_uevent(). >> + */ >> + >> + kobject_get(&elog->kobj); /* extra reference count */ >> rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr); >> if (rc) { >> + kobject_put(&elog->kobj); >> + /* Drop the extra reference count */ >> kobject_put(&elog->kobj); >> return NULL; >> } >> >> kobject_uevent(&elog->kobj, KOBJ_ADD); >> + /* Drop the extra reference count */ >> + kobject_put(&elog->kobj); > > Makes sense, > > Reviewed-by: Oliver O'Halloran <ooh...@gmail.com> > >> >> return elog; > > Does the returned value actually get used anywhere? We'd have a > similar use-after-free problem if it does. This should probably return > an error code rather than the object itself. >
Nope. It isn't being used. I can make it function as void and send v3. Thanks, -Mahesh.