lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+CK2bDrrg0UoJXpeN+Au2-sreYrZ+DHVcEUidzPw2Qk60orgg@mail.gmail.com>
Date: Fri, 24 Oct 2025 09:11:16 -0400
From: Pasha Tatashin <pasha.tatashin@...een.com>
To: Pratyush Yadav <pratyush@...nel.org>
Cc: akpm@...ux-foundation.org, brauner@...nel.org, corbet@....net, 
	graf@...zon.com, jgg@...pe.ca, linux-kernel@...r.kernel.org, 
	linux-kselftest@...r.kernel.org, linux-mm@...ck.org, masahiroy@...nel.org, 
	ojeda@...nel.org, rdunlap@...radead.org, rppt@...nel.org, tj@...nel.org
Subject: Re: [PATCHv7 3/7] kho: drop notifiers

> > -int kho_add_subtree(struct kho_serialization *ser, const char *name, void *fdt)
> > +int kho_add_subtree(const char *name, void *fdt)
> >  {
> > -     int err = 0;
> > -     u64 phys = (u64)virt_to_phys(fdt);
> > -     void *root = page_to_virt(ser->fdt);
> > +     struct kho_sub_fdt *sub_fdt;
> > +     int err;
> >
> > -     err |= fdt_begin_node(root, name);
> > -     err |= fdt_property(root, PROP_SUB_FDT, &phys, sizeof(phys));
> > -     err |= fdt_end_node(root);
> > +     sub_fdt = kmalloc(sizeof(*sub_fdt), GFP_KERNEL);
> > +     if (!sub_fdt)
> > +             return -ENOMEM;
> >
> > -     if (err)
> > -             return err;
> > +     INIT_LIST_HEAD(&sub_fdt->l);
> > +     sub_fdt->name = name;
> > +     sub_fdt->fdt = fdt;
> >
> > -     return kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false);
> > +     mutex_lock(&kho_out.fdts_lock);
> > +     list_add_tail(&sub_fdt->l, &kho_out.sub_fdts);
> > +     err = kho_debugfs_fdt_add(&kho_out.dbg, name, fdt, false);
>
> I think you should remove sub_fdt from the list and kfree() it on error
> here. Otherwise we signal an error to the caller and they might free
> sub_fdt->fdt, which will later result in a use-after-free at
> __kho_finalize().

I think, it is better to simply do:
WARN_ON_ONCE(kho_debugfs_fdt_add(...));
Now debugfs is optional, and there is no reason to return an error to
a caller if kho_debugfs_fdt_add() fails

>
> > +     mutex_unlock(&kho_out.fdts_lock);
> > +
> > +     return err;
> >  }
> >  EXPORT_SYMBOL_GPL(kho_add_subtree);
> >
> > -int register_kho_notifier(struct notifier_block *nb)
> > +void kho_remove_subtree(void *fdt)
> >  {
> > -     return blocking_notifier_chain_register(&kho_out.chain_head, nb);
> > -}
> > -EXPORT_SYMBOL_GPL(register_kho_notifier);
> > +     struct kho_sub_fdt *sub_fdt;
> > +
> > +     mutex_lock(&kho_out.fdts_lock);
> > +     list_for_each_entry(sub_fdt, &kho_out.sub_fdts, l) {
>
> list_for_each_entry_safe() here since we delete.

Not needed, we are breaking from the iterator when deleting.


> >  bool kho_finalized(void)
> > @@ -1232,15 +1248,17 @@ static __init int kho_init(void)
> >  {
> >       int err = 0;
> >       const void *fdt = kho_get_fdt();
> > +     struct page *fdt_page;
> >
> >       if (!kho_enable)
> >               return 0;
> >
> > -     kho_out.ser.fdt = alloc_page(GFP_KERNEL);
> > -     if (!kho_out.ser.fdt) {
> > +     fdt_page = alloc_page(GFP_KERNEL);
> > +     if (!fdt_page) {
> >               err = -ENOMEM;
> >               goto err_free_scratch;
> >       }
> > +     kho_out.fdt = page_to_virt(fdt_page);
> >
> >       err = kho_debugfs_init();
> >       if (err)
> > @@ -1268,8 +1286,8 @@ static __init int kho_init(void)
> >       return 0;
> >
> >  err_free_fdt:
> > -     put_page(kho_out.ser.fdt);
> > -     kho_out.ser.fdt = NULL;
> > +     put_page(fdt_page);
> > +     kho_out.fdt = NULL;
> >  err_free_scratch:
> >       for (int i = 0; i < kho_scratch_cnt; i++) {
> >               void *start = __va(kho_scratch[i].addr);
> > @@ -1280,7 +1298,7 @@ static __init int kho_init(void)
> >       kho_enable = false;
> >       return err;
> >  }
> > -late_initcall(kho_init);
> > +fs_initcall(kho_init);
>
> Is this change related to this patch? Also, why fs_initcall?
>
> >
> >  static void __init kho_release_scratch(void)
> >  {
> > @@ -1416,7 +1434,7 @@ int kho_fill_kimage(struct kimage *image)
> >       if (!kho_out.finalized)
> >               return 0;
> >
> > -     image->kho.fdt = page_to_phys(kho_out.ser.fdt);
> > +     image->kho.fdt = virt_to_phys(kho_out.fdt);
> >
> >       scratch_size = sizeof(*kho_scratch) * kho_scratch_cnt;
> >       scratch = (struct kexec_buf){
> > diff --git a/kernel/kexec_handover_debugfs.c b/kernel/kexec_handover_debugfs.c
> > index a91b279f1b23..46e9e6c0791f 100644
> > --- a/kernel/kexec_handover_debugfs.c
> > +++ b/kernel/kexec_handover_debugfs.c
> > @@ -61,14 +61,17 @@ int kho_debugfs_fdt_add(struct kho_debugfs *dbg, const char *name,
> >       return __kho_debugfs_fdt_add(&dbg->fdt_list, dir, name, fdt);
> >  }
> >
> > -void kho_debugfs_cleanup(struct kho_debugfs *dbg)
> > +void kho_debugfs_fdt_remove(struct kho_debugfs *dbg, void *fdt)
> >  {
> > -     struct fdt_debugfs *ff, *tmp;
> > -
> > -     list_for_each_entry_safe(ff, tmp, &dbg->fdt_list, list) {
> > -             debugfs_remove(ff->file);
> > -             list_del(&ff->list);
> > -             kfree(ff);
> > +     struct fdt_debugfs *ff;
> > +
> > +     list_for_each_entry(ff, &dbg->fdt_list, list) {
>
> list_for_each_entry_safe() here too.

Not needed, we are breaking out on delete/free.


> >  static int kho_test_save_data(struct kho_test_state *state, void *fdt)
> >  {
> >       phys_addr_t *folios_info __free(kvfree) = NULL;
> > @@ -102,6 +86,9 @@ static int kho_test_save_data(struct kho_test_state *state, void *fdt)
> >       if (!err)
> >               state->folios_info = no_free_ptr(folios_info);
> >
> > +     if (!err)
> > +             err = kho_test();
>
> This name is very undescriptive. Also, not the right place to add the
> subtree since the FDT isn't finished yet. I think it should be done from
> kho_test_save() instead. This patch is also missing removing the subtree
> at exit, and that can cause a UAF.
>
> I sent you a patch earlier with my take on how it should be done. I
> still think that is the way to go:
> https://lore.kernel.org/all/mafs0347woui2.fsf@kernel.org/

Sure, I updated to use your suggested changes.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ