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 | 779 | struct module *mod; |
| 780 | 780 | char name[MODULE_NAME_LEN]; |
| 781 | 781 | char buf[MODULE_FLAGS_BUF_SIZE]; |
| 782 | − int ret, forced = 0; | |
| 782 | + int ret, len, forced = 0; | |
| 783 | 783 | |
| 784 | 784 | if (!capable(CAP_SYS_MODULE) || modules_disabled) |
| 785 | 785 | return -EPERM; |
| 786 | 786 | |
| 787 | − if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | |
| 788 | − return -EFAULT; | |
| 789 | − name[MODULE_NAME_LEN-1] = '\0'; | |
| 787 | + len = strncpy_from_user(name, name_user, MODULE_NAME_LEN); | |
| 788 | + if (len == 0 || len == MODULE_NAME_LEN) | |
| 789 | + return -ENOENT; | |
| 790 | + if (len < 0) | |
| 791 | + return len; | |
| 790 | 792 | |
| 791 | 793 | audit_log_kern_module(name); |
| 792 | 794 | |