SYSTEM__MODULE_REQUEST, &ad);
 }
 
+static int selinux_kernel_module_from_file(struct file *file)
+{
+       struct common_audit_data ad;
+       struct inode_security_struct *isec;
+       struct file_security_struct *fsec;
+       u32 sid = current_sid();
+       int rc;
+
+       /* init_module */
+       if (file == NULL)
+               return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
+                                       SYSTEM__MODULE_LOAD, NULL);
+
+       /* finit_module */
+       ad.type = LSM_AUDIT_DATA_PATH;
+       ad.u.path = file->f_path;
+
+       isec = inode_security(file_inode(file));
+       fsec = file->f_security;
+
+       if (sid != fsec->sid) {
+               rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
+               if (rc)
+                       return rc;
+       }
+
+       return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
+                               SYSTEM__MODULE_LOAD, &ad);
+}
+
+static int selinux_kernel_read_file(struct file *file,
+                                   enum kernel_read_file_id id)
+{
+       int rc = 0;
+
+       switch (id) {
+       case READING_MODULE:
+               rc = selinux_kernel_module_from_file(file);
+               break;
+       default:
+               break;
+       }
+
+       return rc;
+}
+
 static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return current_has_perm(p, PROCESS__SETPGID);
        LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
        LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
        LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
+       LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
        LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
        LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
        LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
 
            "setsockcreate", NULL } },
        { "system",
          { "ipc_info", "syslog_read", "syslog_mod",
-           "syslog_console", "module_request", NULL } },
+           "syslog_console", "module_request", "module_load", NULL } },
        { "capability",
          { "chown", "dac_override", "dac_read_search",
            "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",