dl: Only allow unloading modules that are not dependencies

When a module is attempted to be removed its reference counter is always
decremented. This means that repeated rmmod invocations will cause the
module to be unloaded even if another module depends on it.

This may lead to a use-after-free scenario allowing an attacker to execute
arbitrary code and by-pass the UEFI Secure Boot protection.

While being there, add the extern keyword to some function declarations in
that header file.

Fixes: CVE-2020-25632

Reported-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Javier Martinez Canillas authored and Daniel Kiper committed 2021-03-02 15:54:15 +01:00
1 parent f05e79a014
commit 7630ec5397
3 files changed
+19 -5

No files matched your search

+5 -2
View File
@@ -140,8 +140,11 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
if (grub_dl_is_persistent (mod))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module");
if (grub_dl_unref (mod) <= 0)
grub_dl_unload (mod);
if (grub_dl_ref_count (mod) > 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload referenced module");
grub_dl_unref (mod);
grub_dl_unload (mod);
return 0;
}
+9
View File
@@ -549,6 +549,15 @@ grub_dl_unref (grub_dl_t mod)
return --mod->ref_count;
}
int
grub_dl_ref_count (grub_dl_t mod)
{
if (mod == NULL)
return 0;
return mod->ref_count;
}
static void
grub_dl_flush_cache (grub_dl_t mod)
{