Passing a module name longer than MODULE_NAME_LEN to the delete_module syscall results in its silent truncation. This really isn't much of a problem in practice, but it could theoretically lead to the removal of an incorrect module. It is more sensible to return ENAMETOOLONG or ENOENT in such a case. Update the syscall to return ENOENT, as documented in the delete_module(2) man page to mean "No module by that name exists." This is appropriate because a module with a name longer than MODULE_NAME_LEN cannot be loaded in the first place.
Showing the changes to kernel/module (1 of 1 file). Show all
Unified · Split
| @@ -779,14 +779,16 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, · 778 unmodified lines | |||
| 779 | struct module *mod; | 779 | struct module *mod; |
| 780 | char name[MODULE_NAME_LEN]; | 780 | char name[MODULE_NAME_LEN]; |
| 781 | char buf[MODULE_FLAGS_BUF_SIZE]; | 781 | char buf[MODULE_FLAGS_BUF_SIZE]; |
| 782 | int ret, forced = 0; | 782 | int ret, len, forced = 0; |
| 783 | 783 | ||
| 784 | if (!capable(CAP_SYS_MODULE) || modules_disabled) | 784 | if (!capable(CAP_SYS_MODULE) || modules_disabled) |
| 785 | return -EPERM; | 785 | return -EPERM; |
| 786 | 786 | ||
| 787 | if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | 787 | len = strncpy_from_user(name, name_user, MODULE_NAME_LEN); |
| 788 | return -EFAULT; | 788 | if (len == 0 || len == MODULE_NAME_LEN) |
| 789 | name[MODULE_NAME_LEN-1] = '\0'; | 789 | return -ENOENT; |
| 790 | if (len < 0) | ||
| 791 | return len; | ||
| 790 | 792 | ||
| 791 | audit_log_kern_module(name); | 793 | audit_log_kern_module(name); |
| 792 | 794 | ||