#define LSM_AUDIT_DATA_FILE    12
 #define LSM_AUDIT_DATA_IBPKEY  13
 #define LSM_AUDIT_DATA_IBENDPORT 14
+#define LSM_AUDIT_DATA_LOCKDOWN 15
        union   {
                struct path path;
                struct dentry *dentry;
                struct file *file;
                struct lsm_ibpkey_audit *ibpkey;
                struct lsm_ibendport_audit *ibendport;
+               int reason;
        } u;
        /* this union contains LSM specific data */
        union {
 
        LOCKDOWN_CONFIDENTIALITY_MAX,
 };
 
+extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
                       int cap, unsigned int opts);
 
 
 static enum lockdown_reason kernel_locked_down;
 
-static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
-       [LOCKDOWN_NONE] = "none",
-       [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
-       [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
-       [LOCKDOWN_EFI_TEST] = "/dev/efi_test access",
-       [LOCKDOWN_KEXEC] = "kexec of unsigned images",
-       [LOCKDOWN_HIBERNATION] = "hibernation",
-       [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
-       [LOCKDOWN_IOPORT] = "raw io port access",
-       [LOCKDOWN_MSR] = "raw MSR access",
-       [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables",
-       [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage",
-       [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO",
-       [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
-       [LOCKDOWN_MMIOTRACE] = "unsafe mmio",
-       [LOCKDOWN_DEBUGFS] = "debugfs access",
-       [LOCKDOWN_XMON_WR] = "xmon write access",
-       [LOCKDOWN_INTEGRITY_MAX] = "integrity",
-       [LOCKDOWN_KCORE] = "/proc/kcore access",
-       [LOCKDOWN_KPROBES] = "use of kprobes",
-       [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
-       [LOCKDOWN_PERF] = "unsafe use of perf",
-       [LOCKDOWN_TRACEFS] = "use of tracefs",
-       [LOCKDOWN_XMON_RW] = "xmon read and write access",
-       [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
-};
-
 static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
                                                 LOCKDOWN_INTEGRITY_MAX,
                                                 LOCKDOWN_CONFIDENTIALITY_MAX};
 
 #include <linux/dccp.h>
 #include <linux/sctp.h>
 #include <linux/lsm_audit.h>
+#include <linux/security.h>
 
 /**
  * ipv4_skb_to_auditdata : fill auditdata from skb
                                 a->u.ibendport->dev_name,
                                 a->u.ibendport->port);
                break;
+       case LSM_AUDIT_DATA_LOCKDOWN:
+               audit_log_format(ab, " lockdown_reason=");
+               audit_log_string(ab, lockdown_reasons[a->u.reason]);
+               break;
        } /* switch (a->type) */
 }
 
 
 #define LSM_COUNT (__end_lsm_info - __start_lsm_info)
 #define EARLY_LSM_COUNT (__end_early_lsm_info - __start_early_lsm_info)
 
+/*
+ * These are descriptions of the reasons that can be passed to the
+ * security_locked_down() LSM hook. Placing this array here allows
+ * all security modules to use the same descriptions for auditing
+ * purposes.
+ */
+const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
+       [LOCKDOWN_NONE] = "none",
+       [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
+       [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
+       [LOCKDOWN_EFI_TEST] = "/dev/efi_test access",
+       [LOCKDOWN_KEXEC] = "kexec of unsigned images",
+       [LOCKDOWN_HIBERNATION] = "hibernation",
+       [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
+       [LOCKDOWN_IOPORT] = "raw io port access",
+       [LOCKDOWN_MSR] = "raw MSR access",
+       [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables",
+       [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage",
+       [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO",
+       [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
+       [LOCKDOWN_MMIOTRACE] = "unsafe mmio",
+       [LOCKDOWN_DEBUGFS] = "debugfs access",
+       [LOCKDOWN_XMON_WR] = "xmon write access",
+       [LOCKDOWN_INTEGRITY_MAX] = "integrity",
+       [LOCKDOWN_KCORE] = "/proc/kcore access",
+       [LOCKDOWN_KPROBES] = "use of kprobes",
+       [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
+       [LOCKDOWN_PERF] = "unsafe use of perf",
+       [LOCKDOWN_TRACEFS] = "use of tracefs",
+       [LOCKDOWN_XMON_RW] = "xmon read and write access",
+       [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
+};
+
 struct security_hook_heads security_hook_heads __lsm_ro_after_init;
 static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
 
 
 }
 #endif
 
+static int selinux_lockdown(enum lockdown_reason what)
+{
+       struct common_audit_data ad;
+       u32 sid = current_sid();
+       int invalid_reason = (what <= LOCKDOWN_NONE) ||
+                            (what == LOCKDOWN_INTEGRITY_MAX) ||
+                            (what >= LOCKDOWN_CONFIDENTIALITY_MAX);
+
+       if (WARN(invalid_reason, "Invalid lockdown reason")) {
+               audit_log(audit_context(),
+                         GFP_ATOMIC, AUDIT_SELINUX_ERR,
+                         "lockdown_reason=invalid");
+               return -EINVAL;
+       }
+
+       ad.type = LSM_AUDIT_DATA_LOCKDOWN;
+       ad.u.reason = what;
+
+       if (what <= LOCKDOWN_INTEGRITY_MAX)
+               return avc_has_perm(&selinux_state,
+                                   sid, sid, SECCLASS_LOCKDOWN,
+                                   LOCKDOWN__INTEGRITY, &ad);
+       else
+               return avc_has_perm(&selinux_state,
+                                   sid, sid, SECCLASS_LOCKDOWN,
+                                   LOCKDOWN__CONFIDENTIALITY, &ad);
+}
+
 struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
        .lbs_cred = sizeof(struct task_security_struct),
        .lbs_file = sizeof(struct file_security_struct),
        LSM_HOOK_INIT(perf_event_read, selinux_perf_event_read),
        LSM_HOOK_INIT(perf_event_write, selinux_perf_event_write),
 #endif
+
+       LSM_HOOK_INIT(locked_down, selinux_lockdown),
 };
 
 static __init int selinux_init(void)
 
          { COMMON_SOCK_PERMS, NULL } },
        { "perf_event",
          {"open", "cpu", "kernel", "tracepoint", "read", "write"} },
+       { "lockdown",
+         { "integrity", "confidentiality", NULL } },
        { NULL }
   };