Signing a module should only make it trusted by the specific kernel it was built for, not anything else. Loading a signed module meant for a kernel with a different ABI could have interesting effects. Therefore, treat all signatures as invalid when a module is force-loaded.
Showing the changes to kernel/module.c (1 of 1 file). Show all
Unified · Split
| @@ -2686,13 +2686,18 @@ static inline void kmemleak_load_module(const struct module *mod, · 2685 unmodified lines | ||
| 2686 | 2686 | #endif |
| 2687 | 2687 | |
| 2688 | 2688 | #ifdef CONFIG_MODULE_SIG |
| 2689 | −static int module_sig_check(struct load_info *info) | |
| 2689 | +static int module_sig_check(struct load_info *info, int flags) | |
| 2690 | 2690 | { |
| 2691 | 2691 | int err = -ENOKEY; |
| 2692 | 2692 | const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; |
| 2693 | 2693 | const void *mod = info->hdr; |
| 2694 | 2694 | |
| 2695 | − if (info->len > markerlen && | |
| 2695 | + /* | |
| 2696 | + * Require flags == 0, as a module with version information | |
| 2697 | + * removed is no longer the module that was signed | |
| 2698 | + */ | |
| 2699 | + if (flags == 0 && | |
| 2700 | + info->len > markerlen && | |
| 2696 | 2701 | memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { |
| 2697 | 2702 | /* We truncate the module to discard the signature */ |
| 2698 | 2703 | info->len -= markerlen; |
| @@ -2711,7 +2716,7 @@ static int module_sig_check(struct load_info *info) · 12 unmodified lines | ||
| 2711 | 2716 | return err; |
| 2712 | 2717 | } |
| 2713 | 2718 | #else /* !CONFIG_MODULE_SIG */ |
| 2714 | −static int module_sig_check(struct load_info *info) | |
| 2719 | +static int module_sig_check(struct load_info *info, int flags) | |
| 2715 | 2720 | { |
| 2716 | 2721 | return 0; |
| 2717 | 2722 | } |
| @@ -3506,7 +3511,7 @@ static int load_module(struct load_info *info, const char __user *uargs, · 788 unmodified lines | ||
| 3506 | 3511 | long err; |
| 3507 | 3512 | char *after_dashes; |
| 3508 | 3513 | |
| 3509 | − err = module_sig_check(info); | |
| 3514 | + err = module_sig_check(info, flags); | |
| 3510 | 3515 | if (err) |
| 3511 | 3516 | goto free_copy; |
| 3512 | 3517 | |