]> Git Repo - linux.git/commitdiff
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorri...
authorLinus Torvalds <[email protected]>
Sat, 7 Apr 2018 23:53:59 +0000 (16:53 -0700)
committerLinus Torvalds <[email protected]>
Sat, 7 Apr 2018 23:53:59 +0000 (16:53 -0700)
Pull integrity updates from James Morris:
 "A mixture of bug fixes, code cleanup, and continues to close
  IMA-measurement, IMA-appraisal, and IMA-audit gaps.

  Also note the addition of a new cred_getsecid LSM hook by Matthew
  Garrett:

     For IMA purposes, we want to be able to obtain the prepared secid
     in the bprm structure before the credentials are committed. Add a
     cred_getsecid hook that makes this possible.

  which is used by a new CREDS_CHECK target in IMA:

     In ima_bprm_check(), check with both the existing process
     credentials and the credentials that will be committed when the new
     process is started. This will not change behaviour unless the
     system policy is extended to include CREDS_CHECK targets -
     BPRM_CHECK will continue to check the same credentials that it did
     previously"

* 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  ima: Fallback to the builtin hash algorithm
  ima: Add smackfs to the default appraise/measure list
  evm: check for remount ro in progress before writing
  ima: Improvements in ima_appraise_measurement()
  ima: Simplify ima_eventsig_init()
  integrity: Remove unused macro IMA_ACTION_RULE_FLAGS
  ima: drop vla in ima_audit_measurement()
  ima: Fix Kconfig to select TPM 2.0 CRB interface
  evm: Constify *integrity_status_msg[]
  evm: Move evm_hmac and evm_hash from evm_main.c to evm_crypto.c
  fuse: define the filesystem as untrusted
  ima: fail signature verification based on policy
  ima: clear IMA_HASH
  ima: re-evaluate files on privileged mounted filesystems
  ima: fail file signature verification on non-init mounted filesystems
  IMA: Support using new creds in appraisal policy
  security: Add a cred_getsecid hook

1  2 
Documentation/admin-guide/kernel-parameters.txt
include/linux/fs.h
include/linux/lsm_hooks.h
include/linux/security.h
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index 683145d7b054df49b5994e66bbf94e5a591b40a0,2cc17dc7ab8470e59629149e2cc9d3636141dd7d..9a3edf7e901ab331e2b005593d15f43d11cae9b3
                        Use software keyboard repeat
  
        audit=          [KNL] Enable the audit sub-system
 -                      Format: { "0" | "1" } (0 = disabled, 1 = enabled)
 -                      0 - kernel audit is disabled and can not be enabled
 -                          until the next reboot
 +                      Format: { "0" | "1" | "off" | "on" }
 +                      0 | off - kernel audit is disabled and can not be
 +                          enabled until the next reboot
                        unset - kernel audit is initialized but disabled and
                            will be fully enabled by the userspace auditd.
 -                      1 - kernel audit is initialized and partially enabled,
 -                          storing at most audit_backlog_limit messages in
 -                          RAM until it is fully enabled by the userspace
 -                          auditd.
 +                      1 | on - kernel audit is initialized and partially
 +                          enabled, storing at most audit_backlog_limit
 +                          messages in RAM until it is fully enabled by the
 +                          userspace auditd.
                        Default: unset
  
        audit_backlog_limit= [KNL] Set the audit queue size limit.
                        address. The serial port must already be setup
                        and configured. Options are not yet supported.
  
 -      earlyprintk=    [X86,SH,BLACKFIN,ARM,M68k,S390]
 +      earlyprintk=    [X86,SH,ARM,M68k,S390]
                        earlyprintk=vga
                        earlyprintk=efi
                        earlyprintk=sclp
                               If specified, z/VM IUCV HVC accepts connections
                               from listed z/VM user IDs only.
  
 -      hwthread_map=   [METAG] Comma-separated list of Linux cpu id to
 -                              hardware thread id mappings.
 -                              Format: <cpu>:<hwthread>
 -
        keep_bootcon    [KNL]
                        Do not unregister boot console at start. This is only
                        useful for debugging when something happens in the window
  
        ima_policy=     [IMA]
                        The builtin policies to load during IMA setup.
-                       Format: "tcb | appraise_tcb | secure_boot"
+                       Format: "tcb | appraise_tcb | secure_boot |
+                                fail_securely"
  
                        The "tcb" policy measures all programs exec'd, files
                        mmap'd for exec, and all files opened with the read
                        of files (eg. kexec kernel image, kernel modules,
                        firmware, policy, etc) based on file signatures.
  
+                       The "fail_securely" policy forces file signature
+                       verification failure also on privileged mounted
+                       filesystems with the SB_I_UNVERIFIABLE_SIGNATURE
+                       flag.
        ima_tcb         [IMA] Deprecated.  Use ima_policy= instead.
                        Load a policy which meets the needs of the Trusted
                        Computing Base.  This means IMA will measure all
                        of a GICv2 controller even if the memory range
                        exposed by the device tree is too small.
  
 +      irqchip.gicv3_nolpi=
 +                      [ARM, ARM64]
 +                      Force the kernel to ignore the availability of
 +                      LPIs (and by consequence ITSs). Intended for system
 +                      that use the kernel as a bootloader, and thus want
 +                      to let secondary kernels in charge of setting up
 +                      LPIs.
 +
        irqfixup        [HW]
                        When an interrupt is not handled search all handlers
                        for it. Intended to get systems with badly broken
  
                        nohz
                          Disable the tick when a single task runs.
 +
 +                        A residual 1Hz tick is offloaded to workqueues, which you
 +                        need to affine to housekeeping through the global
 +                        workqueue's affinity configured via the
 +                        /sys/devices/virtual/workqueue/cpumask sysfs file, or
 +                        by using the 'domain' flag described below.
 +
 +                        NOTE: by default the global workqueue runs on all CPUs,
 +                        so to protect individual CPUs the 'cpumask' file has to
 +                        be configured manually after bootup.
 +
                        domain
                          Isolate from the general SMP balancing and scheduling
                          algorithms. Note that performing domain isolation this way
        keepinitrd      [HW,ARM]
  
        kernelcore=     [KNL,X86,IA-64,PPC]
 -                      Format: nn[KMGTPE] | "mirror"
 -                      This parameter
 -                      specifies the amount of memory usable by the kernel
 -                      for non-movable allocations.  The requested amount is
 -                      spread evenly throughout all nodes in the system. The
 -                      remaining memory in each node is used for Movable
 -                      pages. In the event, a node is too small to have both
 -                      kernelcore and Movable pages, kernelcore pages will
 -                      take priority and other nodes will have a larger number
 -                      of Movable pages.  The Movable zone is used for the
 -                      allocation of pages that may be reclaimed or moved
 -                      by the page migration subsystem.  This means that
 -                      HugeTLB pages may not be allocated from this zone.
 -                      Note that allocations like PTEs-from-HighMem still
 -                      use the HighMem zone if it exists, and the Normal
 +                      Format: nn[KMGTPE] | nn% | "mirror"
 +                      This parameter specifies the amount of memory usable by
 +                      the kernel for non-movable allocations.  The requested
 +                      amount is spread evenly throughout all nodes in the
 +                      system as ZONE_NORMAL.  The remaining memory is used for
 +                      movable memory in its own zone, ZONE_MOVABLE.  In the
 +                      event, a node is too small to have both ZONE_NORMAL and
 +                      ZONE_MOVABLE, kernelcore memory will take priority and
 +                      other nodes will have a larger ZONE_MOVABLE.
 +
 +                      ZONE_MOVABLE is used for the allocation of pages that
 +                      may be reclaimed or moved by the page migration
 +                      subsystem.  Note that allocations like PTEs-from-HighMem
 +                      still use the HighMem zone if it exists, and the Normal
                        zone if it does not.
  
 -                      Instead of specifying the amount of memory (nn[KMGTPE]),
 -                      you can specify "mirror" option. In case "mirror"
 +                      It is possible to specify the exact amount of memory in
 +                      the form of "nn[KMGTPE]", a percentage of total system
 +                      memory in the form of "nn%", or "mirror".  If "mirror"
                        option is specified, mirrored (reliable) memory is used
                        for non-movable allocations and remaining memory is used
 -                      for Movable pages. nn[KMGTPE] and "mirror" are exclusive,
 -                      so you can NOT specify nn[KMGTPE] and "mirror" at the same
 -                      time.
 +                      for Movable pages.  "nn[KMGTPE]", "nn%", and "mirror"
 +                      are exclusive, so you cannot specify multiple forms.
  
        kgdbdbgp=       [KGDB,HW] kgdb over EHCI usb debug port.
                        Format: <Controller#>[,poll interval]
                        The memory region may be marked as e820 type 12 (0xc)
                        and is NVDIMM or ADR memory.
  
 +      memmap=<size>%<offset>-<oldtype>+<newtype>
 +                      [KNL,ACPI] Convert memory within the specified region
 +                      from <oldtype> to <newtype>. If "-<oldtype>" is left
 +                      out, the whole region will be marked as <newtype>,
 +                      even if previously unavailable. If "+<newtype>" is left
 +                      out, matching memory will be removed. Types are
 +                      specified as e820 types, e.g., 1 = RAM, 2 = reserved,
 +                      3 = ACPI, 12 = PRAM.
 +
        memory_corruption_check=0/1 [X86]
                        Some BIOSes seem to corrupt the first 64k of
                        memory when doing things like suspend/resume.
        mousedev.yres=  [MOUSE] Vertical screen resolution, used for devices
                        reporting absolute coordinates, such as tablets
  
 -      movablecore=nn[KMG]     [KNL,X86,IA-64,PPC] This parameter
 -                      is similar to kernelcore except it specifies the
 -                      amount of memory used for migratable allocations.
 -                      If both kernelcore and movablecore is specified,
 -                      then kernelcore will be at *least* the specified
 -                      value but may be more. If movablecore on its own
 -                      is specified, the administrator must be careful
 +      movablecore=    [KNL,X86,IA-64,PPC]
 +                      Format: nn[KMGTPE] | nn%
 +                      This parameter is the complement to kernelcore=, it
 +                      specifies the amount of memory used for migratable
 +                      allocations.  If both kernelcore and movablecore is
 +                      specified, then kernelcore will be at *least* the
 +                      specified value but may be more.  If movablecore on its
 +                      own is specified, the administrator must be careful
                        that the amount of memory usable for all allocations
                        is not too small.
  
                force   Enable ASPM even on devices that claim not to support it.
                        WARNING: Forcing ASPM on may cause system lockups.
  
 -      pcie_hp=        [PCIE] PCI Express Hotplug driver options:
 -              nomsi   Do not use MSI for PCI Express Native Hotplug (this
 -                      makes all PCIe ports use INTx for hotplug services).
 -
 -      pcie_ports=     [PCIE] PCIe ports handling:
 -              auto    Ask the BIOS whether or not to use native PCIe services
 -                      associated with PCIe ports (PME, hot-plug, AER).  Use
 -                      them only if that is allowed by the BIOS.
 -              native  Use native PCIe services associated with PCIe ports
 -                      unconditionally.
 -              compat  Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe
 -                      ports driver.
 +      pcie_ports=     [PCIE] PCIe port services handling:
 +              native  Use native PCIe services (PME, AER, DPC, PCIe hotplug)
 +                      even if the platform doesn't give the OS permission to
 +                      use them.  This may cause conflicts if the platform
 +                      also tries to use these services.
 +              compat  Disable native PCIe services (PME, AER, DPC, PCIe
 +                      hotplug).
  
        pcie_port_pm=   [PCIE] PCIe port power management handling:
                off     Disable power management of all PCIe ports
  
        usbcore.nousb   [USB] Disable the USB subsystem
  
 +      usbcore.quirks=
 +                      [USB] A list of quirk entries to augment the built-in
 +                      usb core quirk list. List entries are separated by
 +                      commas. Each entry has the form
 +                      VendorID:ProductID:Flags. The IDs are 4-digit hex
 +                      numbers and Flags is a set of letters. Each letter
 +                      will change the built-in quirk; setting it if it is
 +                      clear and clearing it if it is set. The letters have
 +                      the following meanings:
 +                              a = USB_QUIRK_STRING_FETCH_255 (string
 +                                      descriptors must not be fetched using
 +                                      a 255-byte read);
 +                              b = USB_QUIRK_RESET_RESUME (device can't resume
 +                                      correctly so reset it instead);
 +                              c = USB_QUIRK_NO_SET_INTF (device can't handle
 +                                      Set-Interface requests);
 +                              d = USB_QUIRK_CONFIG_INTF_STRINGS (device can't
 +                                      handle its Configuration or Interface
 +                                      strings);
 +                              e = USB_QUIRK_RESET (device can't be reset
 +                                      (e.g morph devices), don't use reset);
 +                              f = USB_QUIRK_HONOR_BNUMINTERFACES (device has
 +                                      more interface descriptions than the
 +                                      bNumInterfaces count, and can't handle
 +                                      talking to these interfaces);
 +                              g = USB_QUIRK_DELAY_INIT (device needs a pause
 +                                      during initialization, after we read
 +                                      the device descriptor);
 +                              h = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL (For
 +                                      high speed and super speed interrupt
 +                                      endpoints, the USB 2.0 and USB 3.0 spec
 +                                      require the interval in microframes (1
 +                                      microframe = 125 microseconds) to be
 +                                      calculated as interval = 2 ^
 +                                      (bInterval-1).
 +                                      Devices with this quirk report their
 +                                      bInterval as the result of this
 +                                      calculation instead of the exponent
 +                                      variable used in the calculation);
 +                              i = USB_QUIRK_DEVICE_QUALIFIER (device can't
 +                                      handle device_qualifier descriptor
 +                                      requests);
 +                              j = USB_QUIRK_IGNORE_REMOTE_WAKEUP (device
 +                                      generates spurious wakeup, ignore
 +                                      remote wakeup capability);
 +                              k = USB_QUIRK_NO_LPM (device can't handle Link
 +                                      Power Management);
 +                              l = USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL
 +                                      (Device reports its bInterval as linear
 +                                      frames instead of the USB 2.0
 +                                      calculation);
 +                              m = USB_QUIRK_DISCONNECT_SUSPEND (Device needs
 +                                      to be disconnected before suspend to
 +                                      prevent spurious wakeup);
 +                              n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a
 +                                      pause after every control message);
 +                      Example: quirks=0781:5580:bk,0a5c:5834:gij
 +
        usbhid.mousepoll=
                        [USBHID] The interval which mice are to be polled at.
  
        usbhid.jspoll=
                        [USBHID] The interval which joysticks are to be polled at.
  
 +      usbhid.kbpoll=
 +                      [USBHID] The interval which keyboards are to be polled at.
 +
        usb-storage.delay_use=
                        [UMS] The delay in seconds before a new device is
                        scanned for Logical Units (default 1).
diff --combined include/linux/fs.h
index 0d798052bd8571198aae7f62f6c517862d121b13,d9e60824c37418fc3bc91efa806f56e23af740fc..1ee7f592e239c3b11587f738b42b06b05291e348
@@@ -1321,6 -1321,8 +1321,8 @@@ extern int send_sigurg(struct fown_stru
  
  /* sb->s_iflags to limit user namespace mounts */
  #define SB_I_USERNS_VISIBLE           0x00000010 /* fstype already mounted */
+ #define SB_I_IMA_UNVERIFIABLE_SIGNATURE       0x00000020
+ #define SB_I_UNTRUSTED_MOUNTER                0x00000040
  
  /* Possible states of 'frozen' field */
  enum {
@@@ -2015,8 -2017,7 +2017,8 @@@ static inline void init_sync_kiocb(stru
  #define I_WB_SWITCH           (1 << 13)
  #define I_OVL_INUSE                   (1 << 14)
  
 -#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
 +#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
 +#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
  #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
  
  extern void __mark_inode_dirty(struct inode *, int);
@@@ -2382,8 -2383,8 +2384,8 @@@ struct audit_names
  struct filename {
        const char              *name;  /* pointer to actual string */
        const __user char       *uptr;  /* original userland pointer */
 -      struct audit_names      *aname;
        int                     refcnt;
 +      struct audit_names      *aname;
        const char              iname[];
  };
  
@@@ -2978,6 -2979,12 +2980,6 @@@ enum 
  
        /* filesystem does not support filling holes */
        DIO_SKIP_HOLES  = 0x02,
 -
 -      /* filesystem can handle aio writes beyond i_size */
 -      DIO_ASYNC_EXTEND = 0x04,
 -
 -      /* inode/fs/bdev does not need truncate protection */
 -      DIO_SKIP_DIO_COUNT = 0x08,
  };
  
  void dio_end_io(struct bio *bio);
index c72c42dbe77b4a1d27bc62df403d62716cbcf25b,bbc6a1240b2e1cec3cbe842d5c77c56b621b2a91..9d0b286f3dbaf56c5362327a1bc82ed1a9132a34
   *    @new points to the new credentials.
   *    @old points to the original credentials.
   *    Transfer data from original creds to new creds
+  * @cred_getsecid:
+  *    Retrieve the security identifier of the cred structure @c
+  *    @c contains the credentials, secid will be placed into @secid.
+  *    In case of failure, @secid will be set to zero.
   * @kernel_act_as:
   *    Set the credentials for a kernel service to act as (subjective context).
   *    @new points to the credentials to be modified.
   *    associated with the TUN device's security structure.
   *    @security pointer to the TUN devices's security structure.
   *
 + * Security hooks for SCTP
 + *
 + * @sctp_assoc_request:
 + *    Passes the @ep and @chunk->skb of the association INIT packet to
 + *    the security module.
 + *    @ep pointer to sctp endpoint structure.
 + *    @skb pointer to skbuff of association packet.
 + *    Return 0 on success, error on failure.
 + * @sctp_bind_connect:
 + *    Validiate permissions required for each address associated with sock
 + *    @sk. Depending on @optname, the addresses will be treated as either
 + *    for a connect or bind service. The @addrlen is calculated on each
 + *    ipv4 and ipv6 address using sizeof(struct sockaddr_in) or
 + *    sizeof(struct sockaddr_in6).
 + *    @sk pointer to sock structure.
 + *    @optname name of the option to validate.
 + *    @address list containing one or more ipv4/ipv6 addresses.
 + *    @addrlen total length of address(s).
 + *    Return 0 on success, error on failure.
 + * @sctp_sk_clone:
 + *    Called whenever a new socket is created by accept(2) (i.e. a TCP
 + *    style socket) or when a socket is 'peeled off' e.g userspace
 + *    calls sctp_peeloff(3).
 + *    @ep pointer to current sctp endpoint structure.
 + *    @sk pointer to current sock structure.
 + *    @sk pointer to new sock structure.
 + *
   * Security hooks for Infiniband
   *
   * @ib_pkey_access:
@@@ -1569,6 -1546,7 +1573,7 @@@ union security_list_options 
        int (*cred_prepare)(struct cred *new, const struct cred *old,
                                gfp_t gfp);
        void (*cred_transfer)(struct cred *new, const struct cred *old);
+       void (*cred_getsecid)(const struct cred *c, u32 *secid);
        int (*kernel_act_as)(struct cred *new, u32 secid);
        int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
        int (*kernel_module_request)(char *kmod_name);
        int (*msg_msg_alloc_security)(struct msg_msg *msg);
        void (*msg_msg_free_security)(struct msg_msg *msg);
  
 -      int (*msg_queue_alloc_security)(struct msg_queue *msq);
 -      void (*msg_queue_free_security)(struct msg_queue *msq);
 -      int (*msg_queue_associate)(struct msg_queue *msq, int msqflg);
 -      int (*msg_queue_msgctl)(struct msg_queue *msq, int cmd);
 -      int (*msg_queue_msgsnd)(struct msg_queue *msq, struct msg_msg *msg,
 +      int (*msg_queue_alloc_security)(struct kern_ipc_perm *msq);
 +      void (*msg_queue_free_security)(struct kern_ipc_perm *msq);
 +      int (*msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg);
 +      int (*msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd);
 +      int (*msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg,
                                int msqflg);
 -      int (*msg_queue_msgrcv)(struct msg_queue *msq, struct msg_msg *msg,
 +      int (*msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg,
                                struct task_struct *target, long type,
                                int mode);
  
 -      int (*shm_alloc_security)(struct shmid_kernel *shp);
 -      void (*shm_free_security)(struct shmid_kernel *shp);
 -      int (*shm_associate)(struct shmid_kernel *shp, int shmflg);
 -      int (*shm_shmctl)(struct shmid_kernel *shp, int cmd);
 -      int (*shm_shmat)(struct shmid_kernel *shp, char __user *shmaddr,
 +      int (*shm_alloc_security)(struct kern_ipc_perm *shp);
 +      void (*shm_free_security)(struct kern_ipc_perm *shp);
 +      int (*shm_associate)(struct kern_ipc_perm *shp, int shmflg);
 +      int (*shm_shmctl)(struct kern_ipc_perm *shp, int cmd);
 +      int (*shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr,
                                int shmflg);
  
 -      int (*sem_alloc_security)(struct sem_array *sma);
 -      void (*sem_free_security)(struct sem_array *sma);
 -      int (*sem_associate)(struct sem_array *sma, int semflg);
 -      int (*sem_semctl)(struct sem_array *sma, int cmd);
 -      int (*sem_semop)(struct sem_array *sma, struct sembuf *sops,
 +      int (*sem_alloc_security)(struct kern_ipc_perm *sma);
 +      void (*sem_free_security)(struct kern_ipc_perm *sma);
 +      int (*sem_associate)(struct kern_ipc_perm *sma, int semflg);
 +      int (*sem_semctl)(struct kern_ipc_perm *sma, int cmd);
 +      int (*sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops,
                                unsigned nsops, int alter);
  
        int (*netlink_send)(struct sock *sk, struct sk_buff *skb);
        int (*tun_dev_attach_queue)(void *security);
        int (*tun_dev_attach)(struct sock *sk, void *security);
        int (*tun_dev_open)(void *security);
 +      int (*sctp_assoc_request)(struct sctp_endpoint *ep,
 +                                struct sk_buff *skb);
 +      int (*sctp_bind_connect)(struct sock *sk, int optname,
 +                               struct sockaddr *address, int addrlen);
 +      void (*sctp_sk_clone)(struct sctp_endpoint *ep, struct sock *sk,
 +                            struct sock *newsk);
  #endif        /* CONFIG_SECURITY_NETWORK */
  
  #ifdef CONFIG_SECURITY_INFINIBAND
  };
  
  struct security_hook_heads {
 -      struct list_head binder_set_context_mgr;
 -      struct list_head binder_transaction;
 -      struct list_head binder_transfer_binder;
 -      struct list_head binder_transfer_file;
 -      struct list_head ptrace_access_check;
 -      struct list_head ptrace_traceme;
 -      struct list_head capget;
 -      struct list_head capset;
 -      struct list_head capable;
 -      struct list_head quotactl;
 -      struct list_head quota_on;
 -      struct list_head syslog;
 -      struct list_head settime;
 -      struct list_head vm_enough_memory;
 -      struct list_head bprm_set_creds;
 -      struct list_head bprm_check_security;
 -      struct list_head bprm_committing_creds;
 -      struct list_head bprm_committed_creds;
 -      struct list_head sb_alloc_security;
 -      struct list_head sb_free_security;
 -      struct list_head sb_copy_data;
 -      struct list_head sb_remount;
 -      struct list_head sb_kern_mount;
 -      struct list_head sb_show_options;
 -      struct list_head sb_statfs;
 -      struct list_head sb_mount;
 -      struct list_head sb_umount;
 -      struct list_head sb_pivotroot;
 -      struct list_head sb_set_mnt_opts;
 -      struct list_head sb_clone_mnt_opts;
 -      struct list_head sb_parse_opts_str;
 -      struct list_head dentry_init_security;
 -      struct list_head dentry_create_files_as;
 +      struct hlist_head binder_set_context_mgr;
 +      struct hlist_head binder_transaction;
 +      struct hlist_head binder_transfer_binder;
 +      struct hlist_head binder_transfer_file;
 +      struct hlist_head ptrace_access_check;
 +      struct hlist_head ptrace_traceme;
 +      struct hlist_head capget;
 +      struct hlist_head capset;
 +      struct hlist_head capable;
 +      struct hlist_head quotactl;
 +      struct hlist_head quota_on;
 +      struct hlist_head syslog;
 +      struct hlist_head settime;
 +      struct hlist_head vm_enough_memory;
 +      struct hlist_head bprm_set_creds;
 +      struct hlist_head bprm_check_security;
 +      struct hlist_head bprm_committing_creds;
 +      struct hlist_head bprm_committed_creds;
 +      struct hlist_head sb_alloc_security;
 +      struct hlist_head sb_free_security;
 +      struct hlist_head sb_copy_data;
 +      struct hlist_head sb_remount;
 +      struct hlist_head sb_kern_mount;
 +      struct hlist_head sb_show_options;
 +      struct hlist_head sb_statfs;
 +      struct hlist_head sb_mount;
 +      struct hlist_head sb_umount;
 +      struct hlist_head sb_pivotroot;
 +      struct hlist_head sb_set_mnt_opts;
 +      struct hlist_head sb_clone_mnt_opts;
 +      struct hlist_head sb_parse_opts_str;
 +      struct hlist_head dentry_init_security;
 +      struct hlist_head dentry_create_files_as;
  #ifdef CONFIG_SECURITY_PATH
 -      struct list_head path_unlink;
 -      struct list_head path_mkdir;
 -      struct list_head path_rmdir;
 -      struct list_head path_mknod;
 -      struct list_head path_truncate;
 -      struct list_head path_symlink;
 -      struct list_head path_link;
 -      struct list_head path_rename;
 -      struct list_head path_chmod;
 -      struct list_head path_chown;
 -      struct list_head path_chroot;
 +      struct hlist_head path_unlink;
 +      struct hlist_head path_mkdir;
 +      struct hlist_head path_rmdir;
 +      struct hlist_head path_mknod;
 +      struct hlist_head path_truncate;
 +      struct hlist_head path_symlink;
 +      struct hlist_head path_link;
 +      struct hlist_head path_rename;
 +      struct hlist_head path_chmod;
 +      struct hlist_head path_chown;
 +      struct hlist_head path_chroot;
  #endif
 -      struct list_head inode_alloc_security;
 -      struct list_head inode_free_security;
 -      struct list_head inode_init_security;
 -      struct list_head inode_create;
 -      struct list_head inode_link;
 -      struct list_head inode_unlink;
 -      struct list_head inode_symlink;
 -      struct list_head inode_mkdir;
 -      struct list_head inode_rmdir;
 -      struct list_head inode_mknod;
 -      struct list_head inode_rename;
 -      struct list_head inode_readlink;
 -      struct list_head inode_follow_link;
 -      struct list_head inode_permission;
 -      struct list_head inode_setattr;
 -      struct list_head inode_getattr;
 -      struct list_head inode_setxattr;
 -      struct list_head inode_post_setxattr;
 -      struct list_head inode_getxattr;
 -      struct list_head inode_listxattr;
 -      struct list_head inode_removexattr;
 -      struct list_head inode_need_killpriv;
 -      struct list_head inode_killpriv;
 -      struct list_head inode_getsecurity;
 -      struct list_head inode_setsecurity;
 -      struct list_head inode_listsecurity;
 -      struct list_head inode_getsecid;
 -      struct list_head inode_copy_up;
 -      struct list_head inode_copy_up_xattr;
 -      struct list_head file_permission;
 -      struct list_head file_alloc_security;
 -      struct list_head file_free_security;
 -      struct list_head file_ioctl;
 -      struct list_head mmap_addr;
 -      struct list_head mmap_file;
 -      struct list_head file_mprotect;
 -      struct list_head file_lock;
 -      struct list_head file_fcntl;
 -      struct list_head file_set_fowner;
 -      struct list_head file_send_sigiotask;
 -      struct list_head file_receive;
 -      struct list_head file_open;
 -      struct list_head task_alloc;
 -      struct list_head task_free;
 -      struct list_head cred_alloc_blank;
 -      struct list_head cred_free;
 -      struct list_head cred_prepare;
 -      struct list_head cred_transfer;
 -      struct list_head cred_getsecid;
 -      struct list_head kernel_act_as;
 -      struct list_head kernel_create_files_as;
 -      struct list_head kernel_read_file;
 -      struct list_head kernel_post_read_file;
 -      struct list_head kernel_module_request;
 -      struct list_head task_fix_setuid;
 -      struct list_head task_setpgid;
 -      struct list_head task_getpgid;
 -      struct list_head task_getsid;
 -      struct list_head task_getsecid;
 -      struct list_head task_setnice;
 -      struct list_head task_setioprio;
 -      struct list_head task_getioprio;
 -      struct list_head task_prlimit;
 -      struct list_head task_setrlimit;
 -      struct list_head task_setscheduler;
 -      struct list_head task_getscheduler;
 -      struct list_head task_movememory;
 -      struct list_head task_kill;
 -      struct list_head task_prctl;
 -      struct list_head task_to_inode;
 -      struct list_head ipc_permission;
 -      struct list_head ipc_getsecid;
 -      struct list_head msg_msg_alloc_security;
 -      struct list_head msg_msg_free_security;
 -      struct list_head msg_queue_alloc_security;
 -      struct list_head msg_queue_free_security;
 -      struct list_head msg_queue_associate;
 -      struct list_head msg_queue_msgctl;
 -      struct list_head msg_queue_msgsnd;
 -      struct list_head msg_queue_msgrcv;
 -      struct list_head shm_alloc_security;
 -      struct list_head shm_free_security;
 -      struct list_head shm_associate;
 -      struct list_head shm_shmctl;
 -      struct list_head shm_shmat;
 -      struct list_head sem_alloc_security;
 -      struct list_head sem_free_security;
 -      struct list_head sem_associate;
 -      struct list_head sem_semctl;
 -      struct list_head sem_semop;
 -      struct list_head netlink_send;
 -      struct list_head d_instantiate;
 -      struct list_head getprocattr;
 -      struct list_head setprocattr;
 -      struct list_head ismaclabel;
 -      struct list_head secid_to_secctx;
 -      struct list_head secctx_to_secid;
 -      struct list_head release_secctx;
 -      struct list_head inode_invalidate_secctx;
 -      struct list_head inode_notifysecctx;
 -      struct list_head inode_setsecctx;
 -      struct list_head inode_getsecctx;
 +      struct hlist_head inode_alloc_security;
 +      struct hlist_head inode_free_security;
 +      struct hlist_head inode_init_security;
 +      struct hlist_head inode_create;
 +      struct hlist_head inode_link;
 +      struct hlist_head inode_unlink;
 +      struct hlist_head inode_symlink;
 +      struct hlist_head inode_mkdir;
 +      struct hlist_head inode_rmdir;
 +      struct hlist_head inode_mknod;
 +      struct hlist_head inode_rename;
 +      struct hlist_head inode_readlink;
 +      struct hlist_head inode_follow_link;
 +      struct hlist_head inode_permission;
 +      struct hlist_head inode_setattr;
 +      struct hlist_head inode_getattr;
 +      struct hlist_head inode_setxattr;
 +      struct hlist_head inode_post_setxattr;
 +      struct hlist_head inode_getxattr;
 +      struct hlist_head inode_listxattr;
 +      struct hlist_head inode_removexattr;
 +      struct hlist_head inode_need_killpriv;
 +      struct hlist_head inode_killpriv;
 +      struct hlist_head inode_getsecurity;
 +      struct hlist_head inode_setsecurity;
 +      struct hlist_head inode_listsecurity;
 +      struct hlist_head inode_getsecid;
 +      struct hlist_head inode_copy_up;
 +      struct hlist_head inode_copy_up_xattr;
 +      struct hlist_head file_permission;
 +      struct hlist_head file_alloc_security;
 +      struct hlist_head file_free_security;
 +      struct hlist_head file_ioctl;
 +      struct hlist_head mmap_addr;
 +      struct hlist_head mmap_file;
 +      struct hlist_head file_mprotect;
 +      struct hlist_head file_lock;
 +      struct hlist_head file_fcntl;
 +      struct hlist_head file_set_fowner;
 +      struct hlist_head file_send_sigiotask;
 +      struct hlist_head file_receive;
 +      struct hlist_head file_open;
 +      struct hlist_head task_alloc;
 +      struct hlist_head task_free;
 +      struct hlist_head cred_alloc_blank;
 +      struct hlist_head cred_free;
 +      struct hlist_head cred_prepare;
 +      struct hlist_head cred_transfer;
++      struct hlist_head cred_getsecid;
 +      struct hlist_head kernel_act_as;
 +      struct hlist_head kernel_create_files_as;
 +      struct hlist_head kernel_read_file;
 +      struct hlist_head kernel_post_read_file;
 +      struct hlist_head kernel_module_request;
 +      struct hlist_head task_fix_setuid;
 +      struct hlist_head task_setpgid;
 +      struct hlist_head task_getpgid;
 +      struct hlist_head task_getsid;
 +      struct hlist_head task_getsecid;
 +      struct hlist_head task_setnice;
 +      struct hlist_head task_setioprio;
 +      struct hlist_head task_getioprio;
 +      struct hlist_head task_prlimit;
 +      struct hlist_head task_setrlimit;
 +      struct hlist_head task_setscheduler;
 +      struct hlist_head task_getscheduler;
 +      struct hlist_head task_movememory;
 +      struct hlist_head task_kill;
 +      struct hlist_head task_prctl;
 +      struct hlist_head task_to_inode;
 +      struct hlist_head ipc_permission;
 +      struct hlist_head ipc_getsecid;
 +      struct hlist_head msg_msg_alloc_security;
 +      struct hlist_head msg_msg_free_security;
 +      struct hlist_head msg_queue_alloc_security;
 +      struct hlist_head msg_queue_free_security;
 +      struct hlist_head msg_queue_associate;
 +      struct hlist_head msg_queue_msgctl;
 +      struct hlist_head msg_queue_msgsnd;
 +      struct hlist_head msg_queue_msgrcv;
 +      struct hlist_head shm_alloc_security;
 +      struct hlist_head shm_free_security;
 +      struct hlist_head shm_associate;
 +      struct hlist_head shm_shmctl;
 +      struct hlist_head shm_shmat;
 +      struct hlist_head sem_alloc_security;
 +      struct hlist_head sem_free_security;
 +      struct hlist_head sem_associate;
 +      struct hlist_head sem_semctl;
 +      struct hlist_head sem_semop;
 +      struct hlist_head netlink_send;
 +      struct hlist_head d_instantiate;
 +      struct hlist_head getprocattr;
 +      struct hlist_head setprocattr;
 +      struct hlist_head ismaclabel;
 +      struct hlist_head secid_to_secctx;
 +      struct hlist_head secctx_to_secid;
 +      struct hlist_head release_secctx;
 +      struct hlist_head inode_invalidate_secctx;
 +      struct hlist_head inode_notifysecctx;
 +      struct hlist_head inode_setsecctx;
 +      struct hlist_head inode_getsecctx;
  #ifdef CONFIG_SECURITY_NETWORK
 -      struct list_head unix_stream_connect;
 -      struct list_head unix_may_send;
 -      struct list_head socket_create;
 -      struct list_head socket_post_create;
 -      struct list_head socket_bind;
 -      struct list_head socket_connect;
 -      struct list_head socket_listen;
 -      struct list_head socket_accept;
 -      struct list_head socket_sendmsg;
 -      struct list_head socket_recvmsg;
 -      struct list_head socket_getsockname;
 -      struct list_head socket_getpeername;
 -      struct list_head socket_getsockopt;
 -      struct list_head socket_setsockopt;
 -      struct list_head socket_shutdown;
 -      struct list_head socket_sock_rcv_skb;
 -      struct list_head socket_getpeersec_stream;
 -      struct list_head socket_getpeersec_dgram;
 -      struct list_head sk_alloc_security;
 -      struct list_head sk_free_security;
 -      struct list_head sk_clone_security;
 -      struct list_head sk_getsecid;
 -      struct list_head sock_graft;
 -      struct list_head inet_conn_request;
 -      struct list_head inet_csk_clone;
 -      struct list_head inet_conn_established;
 -      struct list_head secmark_relabel_packet;
 -      struct list_head secmark_refcount_inc;
 -      struct list_head secmark_refcount_dec;
 -      struct list_head req_classify_flow;
 -      struct list_head tun_dev_alloc_security;
 -      struct list_head tun_dev_free_security;
 -      struct list_head tun_dev_create;
 -      struct list_head tun_dev_attach_queue;
 -      struct list_head tun_dev_attach;
 -      struct list_head tun_dev_open;
 +      struct hlist_head unix_stream_connect;
 +      struct hlist_head unix_may_send;
 +      struct hlist_head socket_create;
 +      struct hlist_head socket_post_create;
 +      struct hlist_head socket_bind;
 +      struct hlist_head socket_connect;
 +      struct hlist_head socket_listen;
 +      struct hlist_head socket_accept;
 +      struct hlist_head socket_sendmsg;
 +      struct hlist_head socket_recvmsg;
 +      struct hlist_head socket_getsockname;
 +      struct hlist_head socket_getpeername;
 +      struct hlist_head socket_getsockopt;
 +      struct hlist_head socket_setsockopt;
 +      struct hlist_head socket_shutdown;
 +      struct hlist_head socket_sock_rcv_skb;
 +      struct hlist_head socket_getpeersec_stream;
 +      struct hlist_head socket_getpeersec_dgram;
 +      struct hlist_head sk_alloc_security;
 +      struct hlist_head sk_free_security;
 +      struct hlist_head sk_clone_security;
 +      struct hlist_head sk_getsecid;
 +      struct hlist_head sock_graft;
 +      struct hlist_head inet_conn_request;
 +      struct hlist_head inet_csk_clone;
 +      struct hlist_head inet_conn_established;
 +      struct hlist_head secmark_relabel_packet;
 +      struct hlist_head secmark_refcount_inc;
 +      struct hlist_head secmark_refcount_dec;
 +      struct hlist_head req_classify_flow;
 +      struct hlist_head tun_dev_alloc_security;
 +      struct hlist_head tun_dev_free_security;
 +      struct hlist_head tun_dev_create;
 +      struct hlist_head tun_dev_attach_queue;
 +      struct hlist_head tun_dev_attach;
 +      struct hlist_head tun_dev_open;
 +      struct hlist_head sctp_assoc_request;
 +      struct hlist_head sctp_bind_connect;
 +      struct hlist_head sctp_sk_clone;
  #endif        /* CONFIG_SECURITY_NETWORK */
  #ifdef CONFIG_SECURITY_INFINIBAND
 -      struct list_head ib_pkey_access;
 -      struct list_head ib_endport_manage_subnet;
 -      struct list_head ib_alloc_security;
 -      struct list_head ib_free_security;
 +      struct hlist_head ib_pkey_access;
 +      struct hlist_head ib_endport_manage_subnet;
 +      struct hlist_head ib_alloc_security;
 +      struct hlist_head ib_free_security;
  #endif        /* CONFIG_SECURITY_INFINIBAND */
  #ifdef CONFIG_SECURITY_NETWORK_XFRM
 -      struct list_head xfrm_policy_alloc_security;
 -      struct list_head xfrm_policy_clone_security;
 -      struct list_head xfrm_policy_free_security;
 -      struct list_head xfrm_policy_delete_security;
 -      struct list_head xfrm_state_alloc;
 -      struct list_head xfrm_state_alloc_acquire;
 -      struct list_head xfrm_state_free_security;
 -      struct list_head xfrm_state_delete_security;
 -      struct list_head xfrm_policy_lookup;
 -      struct list_head xfrm_state_pol_flow_match;
 -      struct list_head xfrm_decode_session;
 +      struct hlist_head xfrm_policy_alloc_security;
 +      struct hlist_head xfrm_policy_clone_security;
 +      struct hlist_head xfrm_policy_free_security;
 +      struct hlist_head xfrm_policy_delete_security;
 +      struct hlist_head xfrm_state_alloc;
 +      struct hlist_head xfrm_state_alloc_acquire;
 +      struct hlist_head xfrm_state_free_security;
 +      struct hlist_head xfrm_state_delete_security;
 +      struct hlist_head xfrm_policy_lookup;
 +      struct hlist_head xfrm_state_pol_flow_match;
 +      struct hlist_head xfrm_decode_session;
  #endif        /* CONFIG_SECURITY_NETWORK_XFRM */
  #ifdef CONFIG_KEYS
 -      struct list_head key_alloc;
 -      struct list_head key_free;
 -      struct list_head key_permission;
 -      struct list_head key_getsecurity;
 +      struct hlist_head key_alloc;
 +      struct hlist_head key_free;
 +      struct hlist_head key_permission;
 +      struct hlist_head key_getsecurity;
  #endif        /* CONFIG_KEYS */
  #ifdef CONFIG_AUDIT
 -      struct list_head audit_rule_init;
 -      struct list_head audit_rule_known;
 -      struct list_head audit_rule_match;
 -      struct list_head audit_rule_free;
 +      struct hlist_head audit_rule_init;
 +      struct hlist_head audit_rule_known;
 +      struct hlist_head audit_rule_match;
 +      struct hlist_head audit_rule_free;
  #endif /* CONFIG_AUDIT */
  #ifdef CONFIG_BPF_SYSCALL
 -      struct list_head bpf;
 -      struct list_head bpf_map;
 -      struct list_head bpf_prog;
 -      struct list_head bpf_map_alloc_security;
 -      struct list_head bpf_map_free_security;
 -      struct list_head bpf_prog_alloc_security;
 -      struct list_head bpf_prog_free_security;
 +      struct hlist_head bpf;
 +      struct hlist_head bpf_map;
 +      struct hlist_head bpf_prog;
 +      struct hlist_head bpf_map_alloc_security;
 +      struct hlist_head bpf_map_free_security;
 +      struct hlist_head bpf_prog_alloc_security;
 +      struct hlist_head bpf_prog_free_security;
  #endif /* CONFIG_BPF_SYSCALL */
  } __randomize_layout;
  
   * For use with generic list macros for common operations.
   */
  struct security_hook_list {
 -      struct list_head                list;
 -      struct list_head                *head;
 +      struct hlist_node               list;
 +      struct hlist_head               *head;
        union security_list_options     hook;
        char                            *lsm;
  } __randomize_layout;
@@@ -2039,7 -2009,7 +2045,7 @@@ static inline void security_delete_hook
        int i;
  
        for (i = 0; i < count; i++)
 -              list_del_rcu(&hooks[i].list);
 +              hlist_del_rcu(&hooks[i].list);
  }
  #endif /* CONFIG_SECURITY_SELINUX_DISABLE */
  
diff --combined include/linux/security.h
index 4a573c3be93d6a1063eb858f072eecd3c29b0d36,116b8717a98c510695c510602628e6a83e479630..200920f521a1ea03aed601eb5ae69bcdd66aac09
@@@ -36,6 -36,7 +36,6 @@@ struct linux_binprm
  struct cred;
  struct rlimit;
  struct siginfo;
 -struct sem_array;
  struct sembuf;
  struct kern_ipc_perm;
  struct audit_context;
@@@ -49,7 -50,9 +49,7 @@@ struct qstr
  struct iattr;
  struct fown_struct;
  struct file_operations;
 -struct shmid_kernel;
  struct msg_msg;
 -struct msg_queue;
  struct xattr;
  struct xfrm_sec_ctx;
  struct mm_struct;
@@@ -112,7 -115,6 +112,7 @@@ struct xfrm_policy
  struct xfrm_state;
  struct xfrm_user_sec_ctx;
  struct seq_file;
 +struct sctp_endpoint;
  
  #ifdef CONFIG_MMU
  extern unsigned long mmap_min_addr;
@@@ -322,6 -324,7 +322,7 @@@ int security_cred_alloc_blank(struct cr
  void security_cred_free(struct cred *cred);
  int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
  void security_transfer_creds(struct cred *new, const struct cred *old);
+ void security_cred_getsecid(const struct cred *c, u32 *secid);
  int security_kernel_act_as(struct cred *new, u32 secid);
  int security_kernel_create_files_as(struct cred *new, struct inode *inode);
  int security_kernel_module_request(char *kmod_name);
@@@ -353,24 -356,24 +354,24 @@@ int security_ipc_permission(struct kern
  void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
  int security_msg_msg_alloc(struct msg_msg *msg);
  void security_msg_msg_free(struct msg_msg *msg);
 -int security_msg_queue_alloc(struct msg_queue *msq);
 -void security_msg_queue_free(struct msg_queue *msq);
 -int security_msg_queue_associate(struct msg_queue *msq, int msqflg);
 -int security_msg_queue_msgctl(struct msg_queue *msq, int cmd);
 -int security_msg_queue_msgsnd(struct msg_queue *msq,
 +int security_msg_queue_alloc(struct kern_ipc_perm *msq);
 +void security_msg_queue_free(struct kern_ipc_perm *msq);
 +int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg);
 +int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd);
 +int security_msg_queue_msgsnd(struct kern_ipc_perm *msq,
                              struct msg_msg *msg, int msqflg);
 -int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 +int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
                              struct task_struct *target, long type, int mode);
 -int security_shm_alloc(struct shmid_kernel *shp);
 -void security_shm_free(struct shmid_kernel *shp);
 -int security_shm_associate(struct shmid_kernel *shp, int shmflg);
 -int security_shm_shmctl(struct shmid_kernel *shp, int cmd);
 -int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg);
 -int security_sem_alloc(struct sem_array *sma);
 -void security_sem_free(struct sem_array *sma);
 -int security_sem_associate(struct sem_array *sma, int semflg);
 -int security_sem_semctl(struct sem_array *sma, int cmd);
 -int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
 +int security_shm_alloc(struct kern_ipc_perm *shp);
 +void security_shm_free(struct kern_ipc_perm *shp);
 +int security_shm_associate(struct kern_ipc_perm *shp, int shmflg);
 +int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd);
 +int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg);
 +int security_sem_alloc(struct kern_ipc_perm *sma);
 +void security_sem_free(struct kern_ipc_perm *sma);
 +int security_sem_associate(struct kern_ipc_perm *sma, int semflg);
 +int security_sem_semctl(struct kern_ipc_perm *sma, int cmd);
 +int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
                        unsigned nsops, int alter);
  void security_d_instantiate(struct dentry *dentry, struct inode *inode);
  int security_getprocattr(struct task_struct *p, char *name, char **value);
@@@ -1043,32 -1046,32 +1044,32 @@@ static inline int security_msg_msg_allo
  static inline void security_msg_msg_free(struct msg_msg *msg)
  { }
  
 -static inline int security_msg_queue_alloc(struct msg_queue *msq)
 +static inline int security_msg_queue_alloc(struct kern_ipc_perm *msq)
  {
        return 0;
  }
  
 -static inline void security_msg_queue_free(struct msg_queue *msq)
 +static inline void security_msg_queue_free(struct kern_ipc_perm *msq)
  { }
  
 -static inline int security_msg_queue_associate(struct msg_queue *msq,
 +static inline int security_msg_queue_associate(struct kern_ipc_perm *msq,
                                               int msqflg)
  {
        return 0;
  }
  
 -static inline int security_msg_queue_msgctl(struct msg_queue *msq, int cmd)
 +static inline int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
  {
        return 0;
  }
  
 -static inline int security_msg_queue_msgsnd(struct msg_queue *msq,
 +static inline int security_msg_queue_msgsnd(struct kern_ipc_perm *msq,
                                            struct msg_msg *msg, int msqflg)
  {
        return 0;
  }
  
 -static inline int security_msg_queue_msgrcv(struct msg_queue *msq,
 +static inline int security_msg_queue_msgrcv(struct kern_ipc_perm *msq,
                                            struct msg_msg *msg,
                                            struct task_struct *target,
                                            long type, int mode)
        return 0;
  }
  
 -static inline int security_shm_alloc(struct shmid_kernel *shp)
 +static inline int security_shm_alloc(struct kern_ipc_perm *shp)
  {
        return 0;
  }
  
 -static inline void security_shm_free(struct shmid_kernel *shp)
 +static inline void security_shm_free(struct kern_ipc_perm *shp)
  { }
  
 -static inline int security_shm_associate(struct shmid_kernel *shp,
 +static inline int security_shm_associate(struct kern_ipc_perm *shp,
                                         int shmflg)
  {
        return 0;
  }
  
 -static inline int security_shm_shmctl(struct shmid_kernel *shp, int cmd)
 +static inline int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
  {
        return 0;
  }
  
 -static inline int security_shm_shmat(struct shmid_kernel *shp,
 +static inline int security_shm_shmat(struct kern_ipc_perm *shp,
                                     char __user *shmaddr, int shmflg)
  {
        return 0;
  }
  
 -static inline int security_sem_alloc(struct sem_array *sma)
 +static inline int security_sem_alloc(struct kern_ipc_perm *sma)
  {
        return 0;
  }
  
 -static inline void security_sem_free(struct sem_array *sma)
 +static inline void security_sem_free(struct kern_ipc_perm *sma)
  { }
  
 -static inline int security_sem_associate(struct sem_array *sma, int semflg)
 +static inline int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
  {
        return 0;
  }
  
 -static inline int security_sem_semctl(struct sem_array *sma, int cmd)
 +static inline int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
  {
        return 0;
  }
  
 -static inline int security_sem_semop(struct sem_array *sma,
 +static inline int security_sem_semop(struct kern_ipc_perm *sma,
                                     struct sembuf *sops, unsigned nsops,
                                     int alter)
  {
@@@ -1227,11 -1230,6 +1228,11 @@@ int security_tun_dev_create(void)
  int security_tun_dev_attach_queue(void *security);
  int security_tun_dev_attach(struct sock *sk, void *security);
  int security_tun_dev_open(void *security);
 +int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb);
 +int security_sctp_bind_connect(struct sock *sk, int optname,
 +                             struct sockaddr *address, int addrlen);
 +void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
 +                          struct sock *newsk);
  
  #else /* CONFIG_SECURITY_NETWORK */
  static inline int security_unix_stream_connect(struct sock *sock,
@@@ -1424,25 -1422,6 +1425,25 @@@ static inline int security_tun_dev_open
  {
        return 0;
  }
 +
 +static inline int security_sctp_assoc_request(struct sctp_endpoint *ep,
 +                                            struct sk_buff *skb)
 +{
 +      return 0;
 +}
 +
 +static inline int security_sctp_bind_connect(struct sock *sk, int optname,
 +                                           struct sockaddr *address,
 +                                           int addrlen)
 +{
 +      return 0;
 +}
 +
 +static inline void security_sctp_sk_clone(struct sctp_endpoint *ep,
 +                                        struct sock *sk,
 +                                        struct sock *newsk)
 +{
 +}
  #endif        /* CONFIG_SECURITY_NETWORK */
  
  #ifdef CONFIG_SECURITY_INFINIBAND
diff --combined security/security.c
index 7301902a872171e028749771f6c599a0b39f103c,957e8bee35546898f51bfcc9b7d7813013e5d68a..d2a84cda7e8d4de1d650a5da1d899a5f5caf0960
@@@ -61,11 -61,11 +61,11 @@@ static void __init do_security_initcall
  int __init security_init(void)
  {
        int i;
 -      struct list_head *list = (struct list_head *) &security_hook_heads;
 +      struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
  
 -      for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct list_head);
 +      for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
             i++)
 -              INIT_LIST_HEAD(&list[i]);
 +              INIT_HLIST_HEAD(&list[i]);
        pr_info("Security Framework initialized\n");
  
        /*
@@@ -163,7 -163,7 +163,7 @@@ void __init security_add_hooks(struct s
  
        for (i = 0; i < count; i++) {
                hooks[i].lsm = lsm;
 -              list_add_tail_rcu(&hooks[i].list, hooks[i].head);
 +              hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
        }
        if (lsm_append(lsm, &lsm_names) < 0)
                panic("%s - Cannot get early memory.\n", __func__);
@@@ -201,7 -201,7 +201,7 @@@ EXPORT_SYMBOL(unregister_lsm_notifier)
        do {                                                    \
                struct security_hook_list *P;                   \
                                                                \
 -              list_for_each_entry(P, &security_hook_heads.FUNC, list) \
 +              hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \
                        P->hook.FUNC(__VA_ARGS__);              \
        } while (0)
  
        do {                                                    \
                struct security_hook_list *P;                   \
                                                                \
 -              list_for_each_entry(P, &security_hook_heads.FUNC, list) { \
 +              hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
                        RC = P->hook.FUNC(__VA_ARGS__);         \
                        if (RC != 0)                            \
                                break;                          \
@@@ -317,7 -317,7 +317,7 @@@ int security_vm_enough_memory_mm(struc
         * agree that it should be set it will. If any module
         * thinks it should not be set it won't.
         */
 -      list_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
 +      hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) {
                rc = hp->hook.vm_enough_memory(mm, pages);
                if (rc <= 0) {
                        cap_sys_admin = 0;
@@@ -805,7 -805,7 +805,7 @@@ int security_inode_getsecurity(struct i
        /*
         * Only one module will provide an attribute with a given name.
         */
 -      list_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
 +      hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
                rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
                if (rc != -EOPNOTSUPP)
                        return rc;
@@@ -823,7 -823,7 +823,7 @@@ int security_inode_setsecurity(struct i
        /*
         * Only one module will provide an attribute with a given name.
         */
 -      list_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
 +      hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
                rc = hp->hook.inode_setsecurity(inode, name, value, size,
                                                                flags);
                if (rc != -EOPNOTSUPP)
@@@ -1005,6 -1005,13 +1005,13 @@@ void security_transfer_creds(struct cre
        call_void_hook(cred_transfer, new, old);
  }
  
+ void security_cred_getsecid(const struct cred *c, u32 *secid)
+ {
+       *secid = 0;
+       call_void_hook(cred_getsecid, c, secid);
+ }
+ EXPORT_SYMBOL(security_cred_getsecid);
  int security_kernel_act_as(struct cred *new, u32 secid)
  {
        return call_int_hook(kernel_act_as, 0, new, secid);
@@@ -1126,7 -1133,7 +1133,7 @@@ int security_task_prctl(int option, uns
        int rc = -ENOSYS;
        struct security_hook_list *hp;
  
 -      list_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
 +      hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
                thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5);
                if (thisrc != -ENOSYS) {
                        rc = thisrc;
@@@ -1163,84 -1170,84 +1170,84 @@@ void security_msg_msg_free(struct msg_m
        call_void_hook(msg_msg_free_security, msg);
  }
  
 -int security_msg_queue_alloc(struct msg_queue *msq)
 +int security_msg_queue_alloc(struct kern_ipc_perm *msq)
  {
        return call_int_hook(msg_queue_alloc_security, 0, msq);
  }
  
 -void security_msg_queue_free(struct msg_queue *msq)
 +void security_msg_queue_free(struct kern_ipc_perm *msq)
  {
        call_void_hook(msg_queue_free_security, msq);
  }
  
 -int security_msg_queue_associate(struct msg_queue *msq, int msqflg)
 +int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
  {
        return call_int_hook(msg_queue_associate, 0, msq, msqflg);
  }
  
 -int security_msg_queue_msgctl(struct msg_queue *msq, int cmd)
 +int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
  {
        return call_int_hook(msg_queue_msgctl, 0, msq, cmd);
  }
  
 -int security_msg_queue_msgsnd(struct msg_queue *msq,
 +int security_msg_queue_msgsnd(struct kern_ipc_perm *msq,
                               struct msg_msg *msg, int msqflg)
  {
        return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg);
  }
  
 -int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 +int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
                               struct task_struct *target, long type, int mode)
  {
        return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode);
  }
  
 -int security_shm_alloc(struct shmid_kernel *shp)
 +int security_shm_alloc(struct kern_ipc_perm *shp)
  {
        return call_int_hook(shm_alloc_security, 0, shp);
  }
  
 -void security_shm_free(struct shmid_kernel *shp)
 +void security_shm_free(struct kern_ipc_perm *shp)
  {
        call_void_hook(shm_free_security, shp);
  }
  
 -int security_shm_associate(struct shmid_kernel *shp, int shmflg)
 +int security_shm_associate(struct kern_ipc_perm *shp, int shmflg)
  {
        return call_int_hook(shm_associate, 0, shp, shmflg);
  }
  
 -int security_shm_shmctl(struct shmid_kernel *shp, int cmd)
 +int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
  {
        return call_int_hook(shm_shmctl, 0, shp, cmd);
  }
  
 -int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg)
 +int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg)
  {
        return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg);
  }
  
 -int security_sem_alloc(struct sem_array *sma)
 +int security_sem_alloc(struct kern_ipc_perm *sma)
  {
        return call_int_hook(sem_alloc_security, 0, sma);
  }
  
 -void security_sem_free(struct sem_array *sma)
 +void security_sem_free(struct kern_ipc_perm *sma)
  {
        call_void_hook(sem_free_security, sma);
  }
  
 -int security_sem_associate(struct sem_array *sma, int semflg)
 +int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
  {
        return call_int_hook(sem_associate, 0, sma, semflg);
  }
  
 -int security_sem_semctl(struct sem_array *sma, int cmd)
 +int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
  {
        return call_int_hook(sem_semctl, 0, sma, cmd);
  }
  
 -int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
 +int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
                        unsigned nsops, int alter)
  {
        return call_int_hook(sem_semop, 0, sma, sops, nsops, alter);
@@@ -1473,7 -1480,6 +1480,7 @@@ void security_inet_conn_established(str
  {
        call_void_hook(inet_conn_established, sk, skb);
  }
 +EXPORT_SYMBOL(security_inet_conn_established);
  
  int security_secmark_relabel_packet(u32 secid)
  {
@@@ -1529,27 -1535,6 +1536,27 @@@ int security_tun_dev_open(void *securit
  }
  EXPORT_SYMBOL(security_tun_dev_open);
  
 +int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb)
 +{
 +      return call_int_hook(sctp_assoc_request, 0, ep, skb);
 +}
 +EXPORT_SYMBOL(security_sctp_assoc_request);
 +
 +int security_sctp_bind_connect(struct sock *sk, int optname,
 +                             struct sockaddr *address, int addrlen)
 +{
 +      return call_int_hook(sctp_bind_connect, 0, sk, optname,
 +                           address, addrlen);
 +}
 +EXPORT_SYMBOL(security_sctp_bind_connect);
 +
 +void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
 +                          struct sock *newsk)
 +{
 +      call_void_hook(sctp_sk_clone, ep, sk, newsk);
 +}
 +EXPORT_SYMBOL(security_sctp_sk_clone);
 +
  #endif        /* CONFIG_SECURITY_NETWORK */
  
  #ifdef CONFIG_SECURITY_INFINIBAND
@@@ -1651,7 -1636,7 +1658,7 @@@ int security_xfrm_state_pol_flow_match(
         * For speed optimization, we explicitly break the loop rather than
         * using the macro
         */
 -      list_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
 +      hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
                                list) {
                rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
                break;
diff --combined security/selinux/hooks.c
index 2b8c55e181aea5815327fa637873513ba885f7ed,b7d4473edbdec75a9bdfd7961bb994038f9c66ce..1eeb70e439d7999646d3fab9c38da5ea60cf1b60
@@@ -67,8 -67,6 +67,8 @@@
  #include <linux/tcp.h>
  #include <linux/udp.h>
  #include <linux/dccp.h>
 +#include <linux/sctp.h>
 +#include <net/sctp/structs.h>
  #include <linux/quota.h>
  #include <linux/un.h>         /* for Unix socket types */
  #include <net/af_unix.h>      /* for Unix socket types */
  #include "audit.h"
  #include "avc_ss.h"
  
 +struct selinux_state selinux_state;
 +
  /* SECMARK reference count */
  static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
  
  #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
 -int selinux_enforcing;
 +static int selinux_enforcing_boot;
  
  static int __init enforcing_setup(char *str)
  {
        unsigned long enforcing;
        if (!kstrtoul(str, 0, &enforcing))
 -              selinux_enforcing = enforcing ? 1 : 0;
 +              selinux_enforcing_boot = enforcing ? 1 : 0;
        return 1;
  }
  __setup("enforcing=", enforcing_setup);
 +#else
 +#define selinux_enforcing_boot 1
  #endif
  
  #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
@@@ -135,19 -129,6 +135,19 @@@ __setup("selinux=", selinux_enabled_set
  int selinux_enabled = 1;
  #endif
  
 +static unsigned int selinux_checkreqprot_boot =
 +      CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 +
 +static int __init checkreqprot_setup(char *str)
 +{
 +      unsigned long checkreqprot;
 +
 +      if (!kstrtoul(str, 0, &checkreqprot))
 +              selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
 +      return 1;
 +}
 +__setup("checkreqprot=", checkreqprot_setup);
 +
  static struct kmem_cache *sel_inode_cache;
  static struct kmem_cache *file_security_cache;
  
   */
  static int selinux_secmark_enabled(void)
  {
 -      return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
 +      return (selinux_policycap_alwaysnetwork() ||
 +              atomic_read(&selinux_secmark_refcount));
  }
  
  /**
   */
  static int selinux_peerlbl_enabled(void)
  {
 -      return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
 +      return (selinux_policycap_alwaysnetwork() ||
 +              netlbl_enabled() || selinux_xfrm_enabled());
  }
  
  static int selinux_netcache_avc_callback(u32 event)
@@@ -285,8 -264,7 +285,8 @@@ static int __inode_security_revalidate(
  
        might_sleep_if(may_sleep);
  
 -      if (ss_initialized && isec->initialized != LABEL_INITIALIZED) {
 +      if (selinux_state.initialized &&
 +          isec->initialized != LABEL_INITIALIZED) {
                if (!may_sleep)
                        return -ECHILD;
  
@@@ -468,14 -446,12 +468,14 @@@ static int may_context_mount_sb_relabel
        const struct task_security_struct *tsec = cred->security;
        int rc;
  
 -      rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
 +      rc = avc_has_perm(&selinux_state,
 +                        tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
                return rc;
  
 -      rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
 +      rc = avc_has_perm(&selinux_state,
 +                        tsec->sid, sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELTO, NULL);
        return rc;
  }
@@@ -486,14 -462,12 +486,14 @@@ static int may_context_mount_inode_rela
  {
        const struct task_security_struct *tsec = cred->security;
        int rc;
 -      rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
 +      rc = avc_has_perm(&selinux_state,
 +                        tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__RELABELFROM, NULL);
        if (rc)
                return rc;
  
 -      rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, sbsec->sid, SECCLASS_FILESYSTEM,
                          FILESYSTEM__ASSOCIATE, NULL);
        return rc;
  }
@@@ -512,7 -486,7 +512,7 @@@ static int selinux_is_sblabel_mnt(struc
                !strcmp(sb->s_type->name, "debugfs") ||
                !strcmp(sb->s_type->name, "tracefs") ||
                !strcmp(sb->s_type->name, "rootfs") ||
 -              (selinux_policycap_cgroupseclabel &&
 +              (selinux_policycap_cgroupseclabel() &&
                 (!strcmp(sb->s_type->name, "cgroup") ||
                  !strcmp(sb->s_type->name, "cgroup2")));
  }
@@@ -612,7 -586,7 +612,7 @@@ static int selinux_get_mnt_opts(const s
        if (!(sbsec->flags & SE_SBINITIALIZED))
                return -EINVAL;
  
 -      if (!ss_initialized)
 +      if (!selinux_state.initialized)
                return -EINVAL;
  
        /* make sure we always check enough bits to cover the mask */
  
        i = 0;
        if (sbsec->flags & FSCONTEXT_MNT) {
 -              rc = security_sid_to_context(sbsec->sid, &context, &len);
 +              rc = security_sid_to_context(&selinux_state, sbsec->sid,
 +                                           &context, &len);
                if (rc)
                        goto out_free;
                opts->mnt_opts[i] = context;
                opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
        }
        if (sbsec->flags & CONTEXT_MNT) {
 -              rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
 +              rc = security_sid_to_context(&selinux_state,
 +                                           sbsec->mntpoint_sid,
 +                                           &context, &len);
                if (rc)
                        goto out_free;
                opts->mnt_opts[i] = context;
                opts->mnt_opts_flags[i++] = CONTEXT_MNT;
        }
        if (sbsec->flags & DEFCONTEXT_MNT) {
 -              rc = security_sid_to_context(sbsec->def_sid, &context, &len);
 +              rc = security_sid_to_context(&selinux_state, sbsec->def_sid,
 +                                           &context, &len);
                if (rc)
                        goto out_free;
                opts->mnt_opts[i] = context;
                struct dentry *root = sbsec->sb->s_root;
                struct inode_security_struct *isec = backing_inode_security(root);
  
 -              rc = security_sid_to_context(isec->sid, &context, &len);
 +              rc = security_sid_to_context(&selinux_state, isec->sid,
 +                                           &context, &len);
                if (rc)
                        goto out_free;
                opts->mnt_opts[i] = context;
@@@ -735,7 -704,7 +735,7 @@@ static int selinux_set_mnt_opts(struct 
  
        mutex_lock(&sbsec->lock);
  
 -      if (!ss_initialized) {
 +      if (!selinux_state.initialized) {
                if (!num_opts) {
                        /* Defer initialization until selinux_complete_init,
                           after the initial policy is loaded and the security
  
                if (flags[i] == SBLABEL_MNT)
                        continue;
 -              rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
 +              rc = security_context_str_to_sid(&selinux_state,
 +                                               mount_options[i], &sid,
 +                                               GFP_KERNEL);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_str_to_sid"
                               "(%s) failed for (dev %s, type %s) errno=%d\n",
                 * Determine the labeling behavior to use for this
                 * filesystem type.
                 */
 -              rc = security_fs_use(sb);
 +              rc = security_fs_use(&selinux_state, sb);
                if (rc) {
                        printk(KERN_WARNING
                                "%s: security_fs_use(%s) returned %d\n",
                }
                if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
                        sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
 -                      rc = security_transition_sid(current_sid(), current_sid(),
 +                      rc = security_transition_sid(&selinux_state,
 +                                                   current_sid(),
 +                                                   current_sid(),
                                                     SECCLASS_FILE, NULL,
                                                     &sbsec->mntpoint_sid);
                        if (rc)
@@@ -1022,7 -987,7 +1022,7 @@@ static int selinux_sb_clone_mnt_opts(co
         * if the parent was able to be mounted it clearly had no special lsm
         * mount options.  thus we can safely deal with this superblock later
         */
 -      if (!ss_initialized)
 +      if (!selinux_state.initialized)
                return 0;
  
        /*
  
        if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
                !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
 -              rc = security_fs_use(newsb);
 +              rc = security_fs_use(&selinux_state, newsb);
                if (rc)
                        goto out;
        }
@@@ -1332,7 -1297,7 +1332,7 @@@ static inline int default_protocol_dgra
  
  static inline u16 socket_type_to_security_class(int family, int type, int protocol)
  {
 -      int extsockclass = selinux_policycap_extsockclass;
 +      int extsockclass = selinux_policycap_extsockclass();
  
        switch (family) {
        case PF_UNIX:
@@@ -1506,8 -1471,7 +1506,8 @@@ static int selinux_genfs_get_sid(struc
                                path++;
                        }
                }
 -              rc = security_genfs_sid(sb->s_type->name, path, tclass, sid);
 +              rc = security_genfs_sid(&selinux_state, sb->s_type->name,
 +                                      path, tclass, sid);
        }
        free_page((unsigned long)buffer);
        return rc;
@@@ -1625,8 -1589,7 +1625,8 @@@ static int inode_doinit_with_dentry(str
                        sid = sbsec->def_sid;
                        rc = 0;
                } else {
 -                      rc = security_context_to_sid_default(context, rc, &sid,
 +                      rc = security_context_to_sid_default(&selinux_state,
 +                                                           context, rc, &sid,
                                                             sbsec->def_sid,
                                                             GFP_NOFS);
                        if (rc) {
                sid = sbsec->sid;
  
                /* Try to obtain a transition SID. */
 -              rc = security_transition_sid(task_sid, sid, sclass, NULL, &sid);
 +              rc = security_transition_sid(&selinux_state, task_sid, sid,
 +                                           sclass, NULL, &sid);
                if (rc)
                        goto out;
                break;
@@@ -1778,11 -1740,9 +1778,11 @@@ static int cred_has_capability(const st
                return -EINVAL;
        }
  
 -      rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
 +      rc = avc_has_perm_noaudit(&selinux_state,
 +                                sid, sid, sclass, av, 0, &avd);
        if (audit == SECURITY_CAP_AUDIT) {
 -              int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
 +              int rc2 = avc_audit(&selinux_state,
 +                                  sid, sid, sclass, av, &avd, rc, &ad, 0);
                if (rc2)
                        return rc2;
        }
@@@ -1808,8 -1768,7 +1808,8 @@@ static int inode_has_perm(const struct 
        sid = cred_sid(cred);
        isec = inode->i_security;
  
 -      return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, isec->sclass, perms, adp);
  }
  
  /* Same as inode_has_perm, but pass explicit audit data containing
@@@ -1882,8 -1841,7 +1882,8 @@@ static int file_has_perm(const struct c
        ad.u.file = file;
  
        if (sid != fsec->sid) {
 -              rc = avc_has_perm(sid, fsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, fsec->sid,
                                  SECCLASS_FD,
                                  FD__USE,
                                  &ad);
@@@ -1925,8 -1883,7 +1925,8 @@@ selinux_determine_inode_label(const str
                *_new_isid = tsec->create_sid;
        } else {
                const struct inode_security_struct *dsec = inode_security(dir);
 -              return security_transition_sid(tsec->sid, dsec->sid, tclass,
 +              return security_transition_sid(&selinux_state, tsec->sid,
 +                                             dsec->sid, tclass,
                                               name, _new_isid);
        }
  
@@@ -1953,8 -1910,7 +1953,8 @@@ static int may_create(struct inode *dir
        ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
  
 -      rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, dsec->sid, SECCLASS_DIR,
                          DIR__ADD_NAME | DIR__SEARCH,
                          &ad);
        if (rc)
        if (rc)
                return rc;
  
 -      rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad);
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, newsid, tclass, FILE__CREATE, &ad);
        if (rc)
                return rc;
  
 -      return avc_has_perm(newsid, sbsec->sid,
 +      return avc_has_perm(&selinux_state,
 +                          newsid, sbsec->sid,
                            SECCLASS_FILESYSTEM,
                            FILESYSTEM__ASSOCIATE, &ad);
  }
@@@ -2000,8 -1954,7 +2000,8 @@@ static int may_link(struct inode *dir
  
        av = DIR__SEARCH;
        av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
 -      rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, av, &ad);
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, dsec->sid, SECCLASS_DIR, av, &ad);
        if (rc)
                return rc;
  
                return 0;
        }
  
 -      rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, isec->sclass, av, &ad);
        return rc;
  }
  
@@@ -2046,19 -1998,16 +2046,19 @@@ static inline int may_rename(struct ino
        ad.type = LSM_AUDIT_DATA_DENTRY;
  
        ad.u.dentry = old_dentry;
 -      rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, old_dsec->sid, SECCLASS_DIR,
                          DIR__REMOVE_NAME | DIR__SEARCH, &ad);
        if (rc)
                return rc;
 -      rc = avc_has_perm(sid, old_isec->sid,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, old_isec->sid,
                          old_isec->sclass, FILE__RENAME, &ad);
        if (rc)
                return rc;
        if (old_is_dir && new_dir != old_dir) {
 -              rc = avc_has_perm(sid, old_isec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, old_isec->sid,
                                  old_isec->sclass, DIR__REPARENT, &ad);
                if (rc)
                        return rc;
        av = DIR__ADD_NAME | DIR__SEARCH;
        if (d_is_positive(new_dentry))
                av |= DIR__REMOVE_NAME;
 -      rc = avc_has_perm(sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
        if (rc)
                return rc;
        if (d_is_positive(new_dentry)) {
                new_isec = backing_inode_security(new_dentry);
                new_is_dir = d_is_dir(new_dentry);
 -              rc = avc_has_perm(sid, new_isec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, new_isec->sid,
                                  new_isec->sclass,
                                  (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
                if (rc)
@@@ -2096,8 -2043,7 +2096,8 @@@ static int superblock_has_perm(const st
        u32 sid = cred_sid(cred);
  
        sbsec = sb->s_security;
 -      return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
 +      return avc_has_perm(&selinux_state,
 +                          sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
  }
  
  /* Convert a Linux mode and permission mask to an access vector. */
@@@ -2160,8 -2106,7 +2160,8 @@@ static inline u32 open_file_to_av(struc
        u32 av = file_to_av(file);
        struct inode *inode = file_inode(file);
  
 -      if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC)
 +      if (selinux_policycap_openperm() &&
 +          inode->i_sb->s_magic != SOCKFS_MAGIC)
                av |= FILE__OPEN;
  
        return av;
@@@ -2174,8 -2119,7 +2174,8 @@@ static int selinux_binder_set_context_m
        u32 mysid = current_sid();
        u32 mgrsid = task_sid(mgr);
  
 -      return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER,
 +      return avc_has_perm(&selinux_state,
 +                          mysid, mgrsid, SECCLASS_BINDER,
                            BINDER__SET_CONTEXT_MGR, NULL);
  }
  
@@@ -2188,15 -2132,13 +2188,15 @@@ static int selinux_binder_transaction(s
        int rc;
  
        if (mysid != fromsid) {
 -              rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER,
 +              rc = avc_has_perm(&selinux_state,
 +                                mysid, fromsid, SECCLASS_BINDER,
                                  BINDER__IMPERSONATE, NULL);
                if (rc)
                        return rc;
        }
  
 -      return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
 +      return avc_has_perm(&selinux_state,
 +                          fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
                            NULL);
  }
  
@@@ -2206,8 -2148,7 +2206,8 @@@ static int selinux_binder_transfer_bind
        u32 fromsid = task_sid(from);
        u32 tosid = task_sid(to);
  
 -      return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
 +      return avc_has_perm(&selinux_state,
 +                          fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
                            NULL);
  }
  
@@@ -2226,8 -2167,7 +2226,8 @@@ static int selinux_binder_transfer_file
        ad.u.path = file->f_path;
  
        if (sid != fsec->sid) {
 -              rc = avc_has_perm(sid, fsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, fsec->sid,
                                  SECCLASS_FD,
                                  FD__USE,
                                  &ad);
                return 0;
  
        isec = backing_inode_security(dentry);
 -      return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, isec->sclass, file_to_av(file),
                            &ad);
  }
  
@@@ -2257,25 -2196,21 +2257,25 @@@ static int selinux_ptrace_access_check(
        u32 csid = task_sid(child);
  
        if (mode & PTRACE_MODE_READ)
 -              return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL);
 +              return avc_has_perm(&selinux_state,
 +                                  sid, csid, SECCLASS_FILE, FILE__READ, NULL);
  
 -      return avc_has_perm(sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
  }
  
  static int selinux_ptrace_traceme(struct task_struct *parent)
  {
 -      return avc_has_perm(task_sid(parent), current_sid(), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          task_sid(parent), current_sid(), SECCLASS_PROCESS,
                            PROCESS__PTRACE, NULL);
  }
  
  static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
                          kernel_cap_t *inheritable, kernel_cap_t *permitted)
  {
 -      return avc_has_perm(current_sid(), task_sid(target), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(target), SECCLASS_PROCESS,
                            PROCESS__GETCAP, NULL);
  }
  
@@@ -2284,8 -2219,7 +2284,8 @@@ static int selinux_capset(struct cred *
                          const kernel_cap_t *inheritable,
                          const kernel_cap_t *permitted)
  {
 -      return avc_has_perm(cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
                            PROCESS__SETCAP, NULL);
  }
  
@@@ -2345,21 -2279,18 +2345,21 @@@ static int selinux_syslog(int type
        switch (type) {
        case SYSLOG_ACTION_READ_ALL:    /* Read last kernel messages */
        case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
 -              return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
        case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
        case SYSLOG_ACTION_CONSOLE_ON:  /* Enable logging to console */
        /* Set level of messages printed to console */
        case SYSLOG_ACTION_CONSOLE_LEVEL:
 -              return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
                                    NULL);
        }
        /* All other syslog types */
 -      return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), SECINITSID_KERNEL,
                            SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
  }
  
@@@ -2420,14 -2351,13 +2420,14 @@@ static int check_nnp_nosuid(const struc
         * policy allows the corresponding permission between
         * the old and new contexts.
         */
 -      if (selinux_policycap_nnp_nosuid_transition) {
 +      if (selinux_policycap_nnp_nosuid_transition()) {
                av = 0;
                if (nnp)
                        av |= PROCESS2__NNP_TRANSITION;
                if (nosuid)
                        av |= PROCESS2__NOSUID_TRANSITION;
 -              rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS2, av, NULL);
                if (!rc)
                        return 0;
         * i.e. SIDs that are guaranteed to only be allowed a subset
         * of the permissions of the current SID.
         */
 -      rc = security_bounded_transition(old_tsec->sid, new_tsec->sid);
 +      rc = security_bounded_transition(&selinux_state, old_tsec->sid,
 +                                       new_tsec->sid);
        if (!rc)
                return 0;
  
@@@ -2491,8 -2420,8 +2491,8 @@@ static int selinux_bprm_set_creds(struc
                        return rc;
        } else {
                /* Check for a default transition on this program. */
 -              rc = security_transition_sid(old_tsec->sid, isec->sid,
 -                                           SECCLASS_PROCESS, NULL,
 +              rc = security_transition_sid(&selinux_state, old_tsec->sid,
 +                                           isec->sid, SECCLASS_PROCESS, NULL,
                                             &new_tsec->sid);
                if (rc)
                        return rc;
        ad.u.file = bprm->file;
  
        if (new_tsec->sid == old_tsec->sid) {
 -              rc = avc_has_perm(old_tsec->sid, isec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                old_tsec->sid, isec->sid,
                                  SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
                if (rc)
                        return rc;
        } else {
                /* Check permissions for the transition. */
 -              rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
                if (rc)
                        return rc;
  
 -              rc = avc_has_perm(new_tsec->sid, isec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                new_tsec->sid, isec->sid,
                                  SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
                if (rc)
                        return rc;
  
                /* Check for shared state */
                if (bprm->unsafe & LSM_UNSAFE_SHARE) {
 -                      rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
 +                      rc = avc_has_perm(&selinux_state,
 +                                        old_tsec->sid, new_tsec->sid,
                                          SECCLASS_PROCESS, PROCESS__SHARE,
                                          NULL);
                        if (rc)
                if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
                        u32 ptsid = ptrace_parent_sid();
                        if (ptsid != 0) {
 -                              rc = avc_has_perm(ptsid, new_tsec->sid,
 +                              rc = avc_has_perm(&selinux_state,
 +                                                ptsid, new_tsec->sid,
                                                  SECCLASS_PROCESS,
                                                  PROCESS__PTRACE, NULL);
                                if (rc)
                /* Enable secure mode for SIDs transitions unless
                   the noatsecure permission is granted between
                   the two SIDs, i.e. ahp returns 0. */
 -              rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                old_tsec->sid, new_tsec->sid,
                                  SECCLASS_PROCESS, PROCESS__NOATSECURE,
                                  NULL);
                bprm->secureexec |= !!rc;
@@@ -2652,8 -2575,7 +2652,8 @@@ static void selinux_bprm_committing_cre
         * higher than the default soft limit for cases where the default is
         * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
         */
 -      rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
 +      rc = avc_has_perm(&selinux_state,
 +                        new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
                          PROCESS__RLIMITINH, NULL);
        if (rc) {
                /* protect against do_prlimit() */
@@@ -2693,8 -2615,7 +2693,8 @@@ static void selinux_bprm_committed_cred
         * This must occur _after_ the task SID has been updated so that any
         * kill done after the flush will be checked against the new SID.
         */
 -      rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
 +      rc = avc_has_perm(&selinux_state,
 +                        osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
        if (rc) {
                if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
                        memset(&itimer, 0, sizeof itimer);
@@@ -2858,9 -2779,7 +2858,9 @@@ static int selinux_sb_remount(struct su
  
                if (flags[i] == SBLABEL_MNT)
                        continue;
 -              rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
 +              rc = security_context_str_to_sid(&selinux_state,
 +                                               mount_options[i], &sid,
 +                                               GFP_KERNEL);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_str_to_sid"
                               "(%s) failed for (dev %s, type %s) errno=%d\n",
@@@ -2985,8 -2904,7 +2985,8 @@@ static int selinux_dentry_init_security
        if (rc)
                return rc;
  
 -      return security_sid_to_context(newsid, (char **)ctx, ctxlen);
 +      return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
 +                                     ctxlen);
  }
  
  static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
@@@ -3040,15 -2958,14 +3040,15 @@@ static int selinux_inode_init_security(
                isec->initialized = LABEL_INITIALIZED;
        }
  
 -      if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
 +      if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
  
        if (name)
                *name = XATTR_SELINUX_SUFFIX;
  
        if (value && len) {
 -              rc = security_sid_to_context_force(newsid, &context, &clen);
 +              rc = security_sid_to_context_force(&selinux_state, newsid,
 +                                                 &context, &clen);
                if (rc)
                        return rc;
                *value = context;
@@@ -3123,8 -3040,7 +3123,8 @@@ static int selinux_inode_follow_link(st
        if (IS_ERR(isec))
                return PTR_ERR(isec);
  
 -      return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad,
 +      return avc_has_perm_flags(&selinux_state,
 +                                sid, isec->sid, isec->sclass, FILE__READ, &ad,
                                  rcu ? MAY_NOT_BLOCK : 0);
  }
  
@@@ -3140,8 -3056,7 +3140,8 @@@ static noinline int audit_inode_permiss
        ad.type = LSM_AUDIT_DATA_INODE;
        ad.u.inode = inode;
  
 -      rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
 +      rc = slow_avc_audit(&selinux_state,
 +                          current_sid(), isec->sid, isec->sclass, perms,
                            audited, denied, result, &ad, flags);
        if (rc)
                return rc;
@@@ -3179,8 -3094,7 +3179,8 @@@ static int selinux_inode_permission(str
        if (IS_ERR(isec))
                return PTR_ERR(isec);
  
 -      rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
 +      rc = avc_has_perm_noaudit(&selinux_state,
 +                                sid, isec->sid, isec->sclass, perms, 0, &avd);
        audited = avc_audit_required(perms, &avd, rc,
                                     from_access ? FILE__AUDIT_ACCESS : 0,
                                     &denied);
@@@ -3212,7 -3126,7 +3212,7 @@@ static int selinux_inode_setattr(struc
                        ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
                return dentry_has_perm(cred, dentry, FILE__SETATTR);
  
 -      if (selinux_policycap_openperm &&
 +      if (selinux_policycap_openperm() &&
            inode->i_sb->s_magic != SOCKFS_MAGIC &&
            (ia_valid & ATTR_SIZE) &&
            !(ia_valid & ATTR_FILE))
@@@ -3269,14 -3183,12 +3269,14 @@@ static int selinux_inode_setxattr(struc
        ad.u.dentry = dentry;
  
        isec = backing_inode_security(dentry);
 -      rc = avc_has_perm(sid, isec->sid, isec->sclass,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, isec->sclass,
                          FILE__RELABELFROM, &ad);
        if (rc)
                return rc;
  
 -      rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
 +      rc = security_context_to_sid(&selinux_state, value, size, &newsid,
 +                                   GFP_KERNEL);
        if (rc == -EINVAL) {
                if (!has_cap_mac_admin(true)) {
                        struct audit_buffer *ab;
  
                        return rc;
                }
 -              rc = security_context_to_sid_force(value, size, &newsid);
 +              rc = security_context_to_sid_force(&selinux_state, value,
 +                                                 size, &newsid);
        }
        if (rc)
                return rc;
  
 -      rc = avc_has_perm(sid, newsid, isec->sclass,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, newsid, isec->sclass,
                          FILE__RELABELTO, &ad);
        if (rc)
                return rc;
  
 -      rc = security_validate_transition(isec->sid, newsid, sid,
 -                                        isec->sclass);
 +      rc = security_validate_transition(&selinux_state, isec->sid, newsid,
 +                                        sid, isec->sclass);
        if (rc)
                return rc;
  
 -      return avc_has_perm(newsid,
 +      return avc_has_perm(&selinux_state,
 +                          newsid,
                            sbsec->sid,
                            SECCLASS_FILESYSTEM,
                            FILESYSTEM__ASSOCIATE,
@@@ -3340,8 -3249,7 +3340,8 @@@ static void selinux_inode_post_setxattr
                return;
        }
  
 -      rc = security_context_to_sid_force(value, size, &newsid);
 +      rc = security_context_to_sid_force(&selinux_state, value, size,
 +                                         &newsid);
        if (rc) {
                printk(KERN_ERR "SELinux:  unable to map context to SID"
                       "for (%s, %lu), rc=%d\n",
@@@ -3416,12 -3324,10 +3416,12 @@@ static int selinux_inode_getsecurity(st
         */
        isec = inode_security(inode);
        if (has_cap_mac_admin(false))
 -              error = security_sid_to_context_force(isec->sid, &context,
 +              error = security_sid_to_context_force(&selinux_state,
 +                                                    isec->sid, &context,
                                                      &size);
        else
 -              error = security_sid_to_context(isec->sid, &context, &size);
 +              error = security_sid_to_context(&selinux_state, isec->sid,
 +                                              &context, &size);
        if (error)
                return error;
        error = size;
@@@ -3447,8 -3353,7 +3447,8 @@@ static int selinux_inode_setsecurity(st
        if (!value || !size)
                return -EACCES;
  
 -      rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
 +      rc = security_context_to_sid(&selinux_state, value, size, &newsid,
 +                                   GFP_KERNEL);
        if (rc)
                return rc;
  
@@@ -3537,7 -3442,7 +3537,7 @@@ static int selinux_file_permission(stru
  
        isec = inode_security(inode);
        if (sid == fsec->sid && fsec->isid == isec->sid &&
 -          fsec->pseqno == avc_policy_seqno())
 +          fsec->pseqno == avc_policy_seqno(&selinux_state))
                /* No change since file_open check. */
                return 0;
  
@@@ -3577,8 -3482,7 +3577,8 @@@ static int ioctl_has_perm(const struct 
        ad.u.op->path = file->f_path;
  
        if (ssid != fsec->sid) {
 -              rc = avc_has_perm(ssid, fsec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                ssid, fsec->sid,
                                SECCLASS_FD,
                                FD__USE,
                                &ad);
                return 0;
  
        isec = inode_security(inode);
 -      rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
 -                      requested, driver, xperm, &ad);
 +      rc = avc_has_extended_perms(&selinux_state,
 +                                  ssid, isec->sid, isec->sclass,
 +                                  requested, driver, xperm, &ad);
  out:
        return rc;
  }
@@@ -3660,8 -3563,7 +3660,8 @@@ static int file_map_prot_check(struct f
                 * private file mapping that will also be writable.
                 * This has an additional check.
                 */
 -              rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, sid, SECCLASS_PROCESS,
                                  PROCESS__EXECMEM, NULL);
                if (rc)
                        goto error;
@@@ -3691,8 -3593,7 +3691,8 @@@ static int selinux_mmap_addr(unsigned l
  
        if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
                u32 sid = current_sid();
 -              rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, sid, SECCLASS_MEMPROTECT,
                                  MEMPROTECT__MMAP_ZERO, NULL);
        }
  
@@@ -3714,7 -3615,7 +3714,7 @@@ static int selinux_mmap_file(struct fil
                        return rc;
        }
  
 -      if (selinux_checkreqprot)
 +      if (selinux_state.checkreqprot)
                prot = reqprot;
  
        return file_map_prot_check(file, prot,
@@@ -3728,7 -3629,7 +3728,7 @@@ static int selinux_file_mprotect(struc
        const struct cred *cred = current_cred();
        u32 sid = cred_sid(cred);
  
 -      if (selinux_checkreqprot)
 +      if (selinux_state.checkreqprot)
                prot = reqprot;
  
        if (default_noexec &&
                int rc = 0;
                if (vma->vm_start >= vma->vm_mm->start_brk &&
                    vma->vm_end <= vma->vm_mm->brk) {
 -                      rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
 +                      rc = avc_has_perm(&selinux_state,
 +                                        sid, sid, SECCLASS_PROCESS,
                                          PROCESS__EXECHEAP, NULL);
                } else if (!vma->vm_file &&
                           ((vma->vm_start <= vma->vm_mm->start_stack &&
                             vma->vm_end >= vma->vm_mm->start_stack) ||
                            vma_is_stack_for_current(vma))) {
 -                      rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
 +                      rc = avc_has_perm(&selinux_state,
 +                                        sid, sid, SECCLASS_PROCESS,
                                          PROCESS__EXECSTACK, NULL);
                } else if (vma->vm_file && vma->anon_vma) {
                        /*
@@@ -3836,8 -3735,7 +3836,8 @@@ static int selinux_file_send_sigiotask(
        else
                perm = signal_to_av(signum);
  
 -      return avc_has_perm(fsec->fown_sid, sid,
 +      return avc_has_perm(&selinux_state,
 +                          fsec->fown_sid, sid,
                            SECCLASS_PROCESS, perm, NULL);
  }
  
@@@ -3863,7 -3761,7 +3863,7 @@@ static int selinux_file_open(struct fil
         * struct as its SID.
         */
        fsec->isid = isec->sid;
 -      fsec->pseqno = avc_policy_seqno();
 +      fsec->pseqno = avc_policy_seqno(&selinux_state);
        /*
         * Since the inode label or policy seqno may have changed
         * between the selinux_inode_permission check and the saving
@@@ -3882,8 -3780,7 +3882,8 @@@ static int selinux_task_alloc(struct ta
  {
        u32 sid = current_sid();
  
 -      return avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
  }
  
  /*
@@@ -3947,6 -3844,11 +3947,11 @@@ static void selinux_cred_transfer(struc
        *tsec = *old_tsec;
  }
  
+ static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
+ {
+       *secid = cred_sid(c);
+ }
  /*
   * set the security data for a kernel service
   * - all the creation contexts are set to unlabelled
@@@ -3957,8 -3859,7 +3962,8 @@@ static int selinux_kernel_act_as(struc
        u32 sid = current_sid();
        int ret;
  
 -      ret = avc_has_perm(sid, secid,
 +      ret = avc_has_perm(&selinux_state,
 +                         sid, secid,
                           SECCLASS_KERNEL_SERVICE,
                           KERNEL_SERVICE__USE_AS_OVERRIDE,
                           NULL);
@@@ -3982,8 -3883,7 +3987,8 @@@ static int selinux_kernel_create_files_
        u32 sid = current_sid();
        int ret;
  
 -      ret = avc_has_perm(sid, isec->sid,
 +      ret = avc_has_perm(&selinux_state,
 +                         sid, isec->sid,
                           SECCLASS_KERNEL_SERVICE,
                           KERNEL_SERVICE__CREATE_FILES_AS,
                           NULL);
@@@ -4000,8 -3900,7 +4005,8 @@@ static int selinux_kernel_module_reques
        ad.type = LSM_AUDIT_DATA_KMOD;
        ad.u.kmod_name = kmod_name;
  
 -      return avc_has_perm(current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
                            SYSTEM__MODULE_REQUEST, &ad);
  }
  
@@@ -4015,8 -3914,7 +4020,8 @@@ static int selinux_kernel_module_from_f
  
        /* init_module */
        if (file == NULL)
 -              return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
 +              return avc_has_perm(&selinux_state,
 +                                  sid, sid, SECCLASS_SYSTEM,
                                        SYSTEM__MODULE_LOAD, NULL);
  
        /* finit_module */
  
        fsec = file->f_security;
        if (sid != fsec->sid) {
 -              rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
                if (rc)
                        return rc;
        }
  
        isec = inode_security(file_inode(file));
 -      return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, SECCLASS_SYSTEM,
                                SYSTEM__MODULE_LOAD, &ad);
  }
  
@@@ -4056,22 -3952,19 +4061,22 @@@ static int selinux_kernel_read_file(str
  
  static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__SETPGID, NULL);
  }
  
  static int selinux_task_getpgid(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__GETPGID, NULL);
  }
  
  static int selinux_task_getsid(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__GETSESSION, NULL);
  }
  
@@@ -4082,22 -3975,19 +4087,22 @@@ static void selinux_task_getsecid(struc
  
  static int selinux_task_setnice(struct task_struct *p, int nice)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
  }
  
  static int selinux_task_setioprio(struct task_struct *p, int ioprio)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
  }
  
  static int selinux_task_getioprio(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__GETSCHED, NULL);
  }
  
@@@ -4112,8 -4002,7 +4117,8 @@@ static int selinux_task_prlimit(const s
                av |= PROCESS__SETRLIMIT;
        if (flags & LSM_PRLIMIT_READ)
                av |= PROCESS__GETRLIMIT;
 -      return avc_has_perm(cred_sid(cred), cred_sid(tcred),
 +      return avc_has_perm(&selinux_state,
 +                          cred_sid(cred), cred_sid(tcred),
                            SECCLASS_PROCESS, av, NULL);
  }
  
@@@ -4127,8 -4016,7 +4132,8 @@@ static int selinux_task_setrlimit(struc
           later be used as a safe reset point for the soft limit
           upon context transitions.  See selinux_bprm_committing_creds. */
        if (old_rlim->rlim_max != new_rlim->rlim_max)
 -              return avc_has_perm(current_sid(), task_sid(p),
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), task_sid(p),
                                    SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
  
        return 0;
  
  static int selinux_task_setscheduler(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
  }
  
  static int selinux_task_getscheduler(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__GETSCHED, NULL);
  }
  
  static int selinux_task_movememory(struct task_struct *p)
  {
 -      return avc_has_perm(current_sid(), task_sid(p), SECCLASS_PROCESS,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), task_sid(p), SECCLASS_PROCESS,
                            PROCESS__SETSCHED, NULL);
  }
  
@@@ -4169,8 -4054,7 +4174,8 @@@ static int selinux_task_kill(struct tas
                secid = current_sid();
        else
                secid = cred_sid(cred);
 -      return avc_has_perm(secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
  }
  
  static void selinux_task_to_inode(struct task_struct *p,
@@@ -4258,23 -4142,6 +4263,23 @@@ static int selinux_parse_skb_ipv4(struc
                break;
        }
  
 +#if IS_ENABLED(CONFIG_IP_SCTP)
 +      case IPPROTO_SCTP: {
 +              struct sctphdr _sctph, *sh;
 +
 +              if (ntohs(ih->frag_off) & IP_OFFSET)
 +                      break;
 +
 +              offset += ihlen;
 +              sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
 +              if (sh == NULL)
 +                      break;
 +
 +              ad->u.net->sport = sh->source;
 +              ad->u.net->dport = sh->dest;
 +              break;
 +      }
 +#endif
        default:
                break;
        }
@@@ -4348,19 -4215,6 +4353,19 @@@ static int selinux_parse_skb_ipv6(struc
                break;
        }
  
 +#if IS_ENABLED(CONFIG_IP_SCTP)
 +      case IPPROTO_SCTP: {
 +              struct sctphdr _sctph, *sh;
 +
 +              sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
 +              if (sh == NULL)
 +                      break;
 +
 +              ad->u.net->sport = sh->source;
 +              ad->u.net->dport = sh->dest;
 +              break;
 +      }
 +#endif
        /* includes fragments */
        default:
                break;
@@@ -4441,8 -4295,7 +4446,8 @@@ static int selinux_skb_peerlbl_sid(stru
        if (unlikely(err))
                return -EACCES;
  
 -      err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
 +      err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
 +                                         nlbl_type, xfrm_sid, sid);
        if (unlikely(err)) {
                printk(KERN_WARNING
                       "SELinux: failure in selinux_skb_peerlbl_sid(),"
@@@ -4470,8 -4323,7 +4475,8 @@@ static int selinux_conn_sid(u32 sk_sid
        int err = 0;
  
        if (skb_sid != SECSID_NULL)
 -              err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
 +              err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
 +                                          conn_sid);
        else
                *conn_sid = sk_sid;
  
@@@ -4488,8 -4340,8 +4493,8 @@@ static int socket_sockcreate_sid(const 
                return 0;
        }
  
 -      return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
 -                                     socksid);
 +      return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
 +                                     secclass, NULL, socksid);
  }
  
  static int sock_has_perm(struct sock *sk, u32 perms)
        ad.u.net = &net;
        ad.u.net->sk = sk;
  
 -      return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), sksec->sid, sksec->sclass, perms,
                            &ad);
  }
  
@@@ -4526,8 -4377,7 +4531,8 @@@ static int selinux_socket_create(int fa
        if (rc)
                return rc;
  
 -      return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
  }
  
  static int selinux_socket_post_create(struct socket *sock, int family,
                sksec = sock->sk->sk_security;
                sksec->sclass = sclass;
                sksec->sid = sid;
 +              /* Allows detection of the first association on this socket */
 +              if (sksec->sclass == SECCLASS_SCTP_SOCKET)
 +                      sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
 +
                err = selinux_netlbl_socket_post_create(sock->sk, family);
        }
  
@@@ -4578,7 -4424,11 +4583,7 @@@ static int selinux_socket_bind(struct s
        if (err)
                goto out;
  
 -      /*
 -       * If PF_INET or PF_INET6, check name_bind permission for the port.
 -       * Multiple address binding for SCTP is not supported yet: we just
 -       * check the first address now.
 -       */
 +      /* If PF_INET or PF_INET6, check name_bind permission for the port. */
        family = sk->sk_family;
        if (family == PF_INET || family == PF_INET6) {
                char *addrp;
                unsigned short snum;
                u32 sid, node_perm;
  
 -              if (family == PF_INET) {
 -                      if (addrlen < sizeof(struct sockaddr_in)) {
 -                              err = -EINVAL;
 -                              goto out;
 -                      }
 +              /*
 +               * sctp_bindx(3) calls via selinux_sctp_bind_connect()
 +               * that validates multiple binding addresses. Because of this
 +               * need to check address->sa_family as it is possible to have
 +               * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
 +               */
 +              switch (address->sa_family) {
 +              case AF_INET:
 +                      if (addrlen < sizeof(struct sockaddr_in))
 +                              return -EINVAL;
                        addr4 = (struct sockaddr_in *)address;
                        snum = ntohs(addr4->sin_port);
                        addrp = (char *)&addr4->sin_addr.s_addr;
 -              } else {
 -                      if (addrlen < SIN6_LEN_RFC2133) {
 -                              err = -EINVAL;
 -                              goto out;
 -                      }
 +                      break;
 +              case AF_INET6:
 +                      if (addrlen < SIN6_LEN_RFC2133)
 +                              return -EINVAL;
                        addr6 = (struct sockaddr_in6 *)address;
                        snum = ntohs(addr6->sin6_port);
                        addrp = (char *)&addr6->sin6_addr.s6_addr;
 +                      break;
 +              default:
 +                      /* Note that SCTP services expect -EINVAL, whereas
 +                       * others expect -EAFNOSUPPORT.
 +                       */
 +                      if (sksec->sclass == SECCLASS_SCTP_SOCKET)
 +                              return -EINVAL;
 +                      else
 +                              return -EAFNOSUPPORT;
                }
  
                if (snum) {
                                ad.u.net = &net;
                                ad.u.net->sport = htons(snum);
                                ad.u.net->family = family;
 -                              err = avc_has_perm(sksec->sid, sid,
 +                              err = avc_has_perm(&selinux_state,
 +                                                 sksec->sid, sid,
                                                   sksec->sclass,
                                                   SOCKET__NAME_BIND, &ad);
                                if (err)
                        node_perm = DCCP_SOCKET__NODE_BIND;
                        break;
  
 +              case SECCLASS_SCTP_SOCKET:
 +                      node_perm = SCTP_SOCKET__NODE_BIND;
 +                      break;
 +
                default:
                        node_perm = RAWIP_SOCKET__NODE_BIND;
                        break;
                ad.u.net->sport = htons(snum);
                ad.u.net->family = family;
  
 -              if (family == PF_INET)
 +              if (address->sa_family == AF_INET)
                        ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
                else
                        ad.u.net->v6info.saddr = addr6->sin6_addr;
  
 -              err = avc_has_perm(sksec->sid, sid,
 +              err = avc_has_perm(&selinux_state,
 +                                 sksec->sid, sid,
                                   sksec->sclass, node_perm, &ad);
                if (err)
                        goto out;
        return err;
  }
  
 -static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
 +/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
 + * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.txt
 + */
 +static int selinux_socket_connect_helper(struct socket *sock,
 +                                       struct sockaddr *address, int addrlen)
  {
        struct sock *sk = sock->sk;
        struct sk_security_struct *sksec = sk->sk_security;
                return err;
  
        /*
 -       * If a TCP or DCCP socket, check name_connect permission for the port.
 +       * If a TCP, DCCP or SCTP socket, check name_connect permission
 +       * for the port.
         */
        if (sksec->sclass == SECCLASS_TCP_SOCKET ||
 -          sksec->sclass == SECCLASS_DCCP_SOCKET) {
 +          sksec->sclass == SECCLASS_DCCP_SOCKET ||
 +          sksec->sclass == SECCLASS_SCTP_SOCKET) {
                struct common_audit_data ad;
                struct lsm_network_audit net = {0,};
                struct sockaddr_in *addr4 = NULL;
                unsigned short snum;
                u32 sid, perm;
  
 -              if (sk->sk_family == PF_INET) {
 +              /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
 +               * that validates multiple connect addresses. Because of this
 +               * need to check address->sa_family as it is possible to have
 +               * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
 +               */
 +              switch (address->sa_family) {
 +              case AF_INET:
                        addr4 = (struct sockaddr_in *)address;
                        if (addrlen < sizeof(struct sockaddr_in))
                                return -EINVAL;
                        snum = ntohs(addr4->sin_port);
 -              } else {
 +                      break;
 +              case AF_INET6:
                        addr6 = (struct sockaddr_in6 *)address;
                        if (addrlen < SIN6_LEN_RFC2133)
                                return -EINVAL;
                        snum = ntohs(addr6->sin6_port);
 +                      break;
 +              default:
 +                      /* Note that SCTP services expect -EINVAL, whereas
 +                       * others expect -EAFNOSUPPORT.
 +                       */
 +                      if (sksec->sclass == SECCLASS_SCTP_SOCKET)
 +                              return -EINVAL;
 +                      else
 +                              return -EAFNOSUPPORT;
                }
  
                err = sel_netport_sid(sk->sk_protocol, snum, &sid);
                if (err)
 -                      goto out;
 +                      return err;
  
 -              perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
 -                     TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
 +              switch (sksec->sclass) {
 +              case SECCLASS_TCP_SOCKET:
 +                      perm = TCP_SOCKET__NAME_CONNECT;
 +                      break;
 +              case SECCLASS_DCCP_SOCKET:
 +                      perm = DCCP_SOCKET__NAME_CONNECT;
 +                      break;
 +              case SECCLASS_SCTP_SOCKET:
 +                      perm = SCTP_SOCKET__NAME_CONNECT;
 +                      break;
 +              }
  
                ad.type = LSM_AUDIT_DATA_NET;
                ad.u.net = &net;
                ad.u.net->dport = htons(snum);
                ad.u.net->family = sk->sk_family;
 -              err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
 +              err = avc_has_perm(&selinux_state,
 +                                 sksec->sid, sid, sksec->sclass, perm, &ad);
                if (err)
 -                      goto out;
 +                      return err;
        }
  
 -      err = selinux_netlbl_socket_connect(sk, address);
 +      return 0;
 +}
  
 -out:
 -      return err;
 +/* Supports connect(2), see comments in selinux_socket_connect_helper() */
 +static int selinux_socket_connect(struct socket *sock,
 +                                struct sockaddr *address, int addrlen)
 +{
 +      int err;
 +      struct sock *sk = sock->sk;
 +
 +      err = selinux_socket_connect_helper(sock, address, addrlen);
 +      if (err)
 +              return err;
 +
 +      return selinux_netlbl_socket_connect(sk, address);
  }
  
  static int selinux_socket_listen(struct socket *sock, int backlog)
@@@ -4880,8 -4668,7 +4885,8 @@@ static int selinux_socket_unix_stream_c
        ad.u.net = &net;
        ad.u.net->sk = other;
  
 -      err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
 +      err = avc_has_perm(&selinux_state,
 +                         sksec_sock->sid, sksec_other->sid,
                           sksec_other->sclass,
                           UNIX_STREAM_SOCKET__CONNECTTO, &ad);
        if (err)
  
        /* server child socket */
        sksec_new->peer_sid = sksec_sock->sid;
 -      err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid,
 -                                  &sksec_new->sid);
 +      err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
 +                                  sksec_sock->sid, &sksec_new->sid);
        if (err)
                return err;
  
@@@ -4912,8 -4699,7 +4917,8 @@@ static int selinux_socket_unix_may_send
        ad.u.net = &net;
        ad.u.net->sk = other->sk;
  
 -      return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
 +      return avc_has_perm(&selinux_state,
 +                          ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
                            &ad);
  }
  
@@@ -4928,8 -4714,7 +4933,8 @@@ static int selinux_inet_sys_rcv_skb(str
        err = sel_netif_sid(ns, ifindex, &if_sid);
        if (err)
                return err;
 -      err = avc_has_perm(peer_sid, if_sid,
 +      err = avc_has_perm(&selinux_state,
 +                         peer_sid, if_sid,
                           SECCLASS_NETIF, NETIF__INGRESS, ad);
        if (err)
                return err;
        err = sel_netnode_sid(addrp, family, &node_sid);
        if (err)
                return err;
 -      return avc_has_perm(peer_sid, node_sid,
 +      return avc_has_perm(&selinux_state,
 +                          peer_sid, node_sid,
                            SECCLASS_NODE, NODE__RECVFROM, ad);
  }
  
@@@ -4961,8 -4745,7 +4966,8 @@@ static int selinux_sock_rcv_skb_compat(
                return err;
  
        if (selinux_secmark_enabled()) {
 -              err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
 +              err = avc_has_perm(&selinux_state,
 +                                 sk_sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
                if (err)
                        return err;
@@@ -4999,7 -4782,7 +5004,7 @@@ static int selinux_socket_sock_rcv_skb(
         * to the selinux_sock_rcv_skb_compat() function to deal with the
         * special handling.  We do this in an attempt to keep this function
         * as fast and as clean as possible. */
 -      if (!selinux_policycap_netpeer)
 +      if (!selinux_policycap_netpeer())
                return selinux_sock_rcv_skb_compat(sk, skb, family);
  
        secmark_active = selinux_secmark_enabled();
                        selinux_netlbl_err(skb, family, err, 0);
                        return err;
                }
 -              err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
 +              err = avc_has_perm(&selinux_state,
 +                                 sk_sid, peer_sid, SECCLASS_PEER,
                                   PEER__RECV, &ad);
                if (err) {
                        selinux_netlbl_err(skb, family, err, 0);
        }
  
        if (secmark_active) {
 -              err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
 +              err = avc_has_perm(&selinux_state,
 +                                 sk_sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
                if (err)
                        return err;
@@@ -5057,14 -4838,12 +5062,14 @@@ static int selinux_socket_getpeersec_st
        u32 peer_sid = SECSID_NULL;
  
        if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
 -          sksec->sclass == SECCLASS_TCP_SOCKET)
 +          sksec->sclass == SECCLASS_TCP_SOCKET ||
 +          sksec->sclass == SECCLASS_SCTP_SOCKET)
                peer_sid = sksec->peer_sid;
        if (peer_sid == SECSID_NULL)
                return -ENOPROTOOPT;
  
 -      err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
 +      err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
 +                                    &scontext_len);
        if (err)
                return err;
  
@@@ -5172,172 -4951,6 +5177,172 @@@ static void selinux_sock_graft(struct s
        sksec->sclass = isec->sclass;
  }
  
 +/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
 + * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
 + * already present).
 + */
 +static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
 +                                    struct sk_buff *skb)
 +{
 +      struct sk_security_struct *sksec = ep->base.sk->sk_security;
 +      struct common_audit_data ad;
 +      struct lsm_network_audit net = {0,};
 +      u8 peerlbl_active;
 +      u32 peer_sid = SECINITSID_UNLABELED;
 +      u32 conn_sid;
 +      int err = 0;
 +
 +      if (!selinux_policycap_extsockclass())
 +              return 0;
 +
 +      peerlbl_active = selinux_peerlbl_enabled();
 +
 +      if (peerlbl_active) {
 +              /* This will return peer_sid = SECSID_NULL if there are
 +               * no peer labels, see security_net_peersid_resolve().
 +               */
 +              err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
 +                                            &peer_sid);
 +              if (err)
 +                      return err;
 +
 +              if (peer_sid == SECSID_NULL)
 +                      peer_sid = SECINITSID_UNLABELED;
 +      }
 +
 +      if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
 +              sksec->sctp_assoc_state = SCTP_ASSOC_SET;
 +
 +              /* Here as first association on socket. As the peer SID
 +               * was allowed by peer recv (and the netif/node checks),
 +               * then it is approved by policy and used as the primary
 +               * peer SID for getpeercon(3).
 +               */
 +              sksec->peer_sid = peer_sid;
 +      } else if  (sksec->peer_sid != peer_sid) {
 +              /* Other association peer SIDs are checked to enforce
 +               * consistency among the peer SIDs.
 +               */
 +              ad.type = LSM_AUDIT_DATA_NET;
 +              ad.u.net = &net;
 +              ad.u.net->sk = ep->base.sk;
 +              err = avc_has_perm(&selinux_state,
 +                                 sksec->peer_sid, peer_sid, sksec->sclass,
 +                                 SCTP_SOCKET__ASSOCIATION, &ad);
 +              if (err)
 +                      return err;
 +      }
 +
 +      /* Compute the MLS component for the connection and store
 +       * the information in ep. This will be used by SCTP TCP type
 +       * sockets and peeled off connections as they cause a new
 +       * socket to be generated. selinux_sctp_sk_clone() will then
 +       * plug this into the new socket.
 +       */
 +      err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
 +      if (err)
 +              return err;
 +
 +      ep->secid = conn_sid;
 +      ep->peer_secid = peer_sid;
 +
 +      /* Set any NetLabel labels including CIPSO/CALIPSO options. */
 +      return selinux_netlbl_sctp_assoc_request(ep, skb);
 +}
 +
 +/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
 + * based on their @optname.
 + */
 +static int selinux_sctp_bind_connect(struct sock *sk, int optname,
 +                                   struct sockaddr *address,
 +                                   int addrlen)
 +{
 +      int len, err = 0, walk_size = 0;
 +      void *addr_buf;
 +      struct sockaddr *addr;
 +      struct socket *sock;
 +
 +      if (!selinux_policycap_extsockclass())
 +              return 0;
 +
 +      /* Process one or more addresses that may be IPv4 or IPv6 */
 +      sock = sk->sk_socket;
 +      addr_buf = address;
 +
 +      while (walk_size < addrlen) {
 +              addr = addr_buf;
 +              switch (addr->sa_family) {
 +              case AF_INET:
 +                      len = sizeof(struct sockaddr_in);
 +                      break;
 +              case AF_INET6:
 +                      len = sizeof(struct sockaddr_in6);
 +                      break;
 +              default:
 +                      return -EAFNOSUPPORT;
 +              }
 +
 +              err = -EINVAL;
 +              switch (optname) {
 +              /* Bind checks */
 +              case SCTP_PRIMARY_ADDR:
 +              case SCTP_SET_PEER_PRIMARY_ADDR:
 +              case SCTP_SOCKOPT_BINDX_ADD:
 +                      err = selinux_socket_bind(sock, addr, len);
 +                      break;
 +              /* Connect checks */
 +              case SCTP_SOCKOPT_CONNECTX:
 +              case SCTP_PARAM_SET_PRIMARY:
 +              case SCTP_PARAM_ADD_IP:
 +              case SCTP_SENDMSG_CONNECT:
 +                      err = selinux_socket_connect_helper(sock, addr, len);
 +                      if (err)
 +                              return err;
 +
 +                      /* As selinux_sctp_bind_connect() is called by the
 +                       * SCTP protocol layer, the socket is already locked,
 +                       * therefore selinux_netlbl_socket_connect_locked() is
 +                       * is called here. The situations handled are:
 +                       * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
 +                       * whenever a new IP address is added or when a new
 +                       * primary address is selected.
 +                       * Note that an SCTP connect(2) call happens before
 +                       * the SCTP protocol layer and is handled via
 +                       * selinux_socket_connect().
 +                       */
 +                      err = selinux_netlbl_socket_connect_locked(sk, addr);
 +                      break;
 +              }
 +
 +              if (err)
 +                      return err;
 +
 +              addr_buf += len;
 +              walk_size += len;
 +      }
 +
 +      return 0;
 +}
 +
 +/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
 +static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
 +                                struct sock *newsk)
 +{
 +      struct sk_security_struct *sksec = sk->sk_security;
 +      struct sk_security_struct *newsksec = newsk->sk_security;
 +
 +      /* If policy does not support SECCLASS_SCTP_SOCKET then call
 +       * the non-sctp clone version.
 +       */
 +      if (!selinux_policycap_extsockclass())
 +              return selinux_sk_clone_security(sk, newsk);
 +
 +      newsksec->sid = ep->secid;
 +      newsksec->peer_sid = ep->peer_secid;
 +      newsksec->sclass = sksec->sclass;
 +      selinux_netlbl_sctp_sk_clone(sk, newsk);
 +}
 +
  static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
                                     struct request_sock *req)
  {
@@@ -5396,9 -5009,7 +5401,9 @@@ static int selinux_secmark_relabel_pack
        __tsec = current_security();
        tsid = __tsec->sid;
  
 -      return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
 +                          NULL);
  }
  
  static void selinux_secmark_refcount_inc(void)
@@@ -5446,8 -5057,7 +5451,8 @@@ static int selinux_tun_dev_create(void
         * connections unlike traditional sockets - check the TUN driver to
         * get a better understanding of why this socket is special */
  
 -      return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
 +      return avc_has_perm(&selinux_state,
 +                          sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
                            NULL);
  }
  
@@@ -5455,8 -5065,7 +5460,8 @@@ static int selinux_tun_dev_attach_queue
  {
        struct tun_security_struct *tunsec = security;
  
 -      return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
 +      return avc_has_perm(&selinux_state,
 +                          current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
                            TUN_SOCKET__ATTACH_QUEUE, NULL);
  }
  
@@@ -5484,13 -5093,11 +5489,13 @@@ static int selinux_tun_dev_open(void *s
        u32 sid = current_sid();
        int err;
  
 -      err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,
 +      err = avc_has_perm(&selinux_state,
 +                         sid, tunsec->sid, SECCLASS_TUN_SOCKET,
                           TUN_SOCKET__RELABELFROM, NULL);
        if (err)
                return err;
 -      err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET,
 +      err = avc_has_perm(&selinux_state,
 +                         sid, sid, SECCLASS_TUN_SOCKET,
                           TUN_SOCKET__RELABELTO, NULL);
        if (err)
                return err;
@@@ -5521,8 -5128,7 +5526,8 @@@ static int selinux_nlmsg_perm(struct so
                               sk->sk_protocol, nlh->nlmsg_type,
                               secclass_map[sksec->sclass - 1].name,
                               task_pid_nr(current), current->comm);
 -                      if (!selinux_enforcing || security_get_allow_unknown())
 +                      if (!enforcing_enabled(&selinux_state) ||
 +                          security_get_allow_unknown(&selinux_state))
                                err = 0;
                }
  
@@@ -5552,7 -5158,7 +5557,7 @@@ static unsigned int selinux_ip_forward(
        u8 netlbl_active;
        u8 peerlbl_active;
  
 -      if (!selinux_policycap_netpeer)
 +      if (!selinux_policycap_netpeer())
                return NF_ACCEPT;
  
        secmark_active = selinux_secmark_enabled();
        }
  
        if (secmark_active)
 -              if (avc_has_perm(peer_sid, skb->secmark,
 +              if (avc_has_perm(&selinux_state,
 +                               peer_sid, skb->secmark,
                                 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
                        return NF_DROP;
  
@@@ -5694,8 -5299,7 +5699,8 @@@ static unsigned int selinux_ip_postrout
                return NF_DROP;
  
        if (selinux_secmark_enabled())
 -              if (avc_has_perm(sksec->sid, skb->secmark,
 +              if (avc_has_perm(&selinux_state,
 +                               sksec->sid, skb->secmark,
                                 SECCLASS_PACKET, PACKET__SEND, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
  
@@@ -5723,7 -5327,7 +5728,7 @@@ static unsigned int selinux_ip_postrout
         * to the selinux_ip_postroute_compat() function to deal with the
         * special handling.  We do this in an attempt to keep this function
         * as fast and as clean as possible. */
 -      if (!selinux_policycap_netpeer)
 +      if (!selinux_policycap_netpeer())
                return selinux_ip_postroute_compat(skb, ifindex, family);
  
        secmark_active = selinux_secmark_enabled();
                return NF_DROP;
  
        if (secmark_active)
 -              if (avc_has_perm(peer_sid, skb->secmark,
 +              if (avc_has_perm(&selinux_state,
 +                               peer_sid, skb->secmark,
                                 SECCLASS_PACKET, secmark_perm, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
  
  
                if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
                        return NF_DROP;
 -              if (avc_has_perm(peer_sid, if_sid,
 +              if (avc_has_perm(&selinux_state,
 +                               peer_sid, if_sid,
                                 SECCLASS_NETIF, NETIF__EGRESS, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
  
                if (sel_netnode_sid(addrp, family, &node_sid))
                        return NF_DROP;
 -              if (avc_has_perm(peer_sid, node_sid,
 +              if (avc_has_perm(&selinux_state,
 +                               peer_sid, node_sid,
                                 SECCLASS_NODE, NODE__SENDTO, &ad))
                        return NF_DROP_ERR(-ECONNREFUSED);
        }
@@@ -5925,8 -5526,7 +5930,8 @@@ static int ipc_has_perm(struct kern_ipc
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = ipc_perms->key;
  
 -      return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, isec->sclass, perms, &ad);
  }
  
  static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
@@@ -5940,54 -5540,52 +5945,54 @@@ static void selinux_msg_msg_free_securi
  }
  
  /* message queue security operations */
 -static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
 +static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
  
 -      rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ);
 +      rc = ipc_alloc_security(msq, SECCLASS_MSGQ);
        if (rc)
                return rc;
  
 -      isec = msq->q_perm.security;
 +      isec = msq->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = msq->q_perm.key;
 +      ad.u.ipc_id = msq->key;
  
 -      rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, SECCLASS_MSGQ,
                          MSGQ__CREATE, &ad);
        if (rc) {
 -              ipc_free_security(&msq->q_perm);
 +              ipc_free_security(msq);
                return rc;
        }
        return 0;
  }
  
 -static void selinux_msg_queue_free_security(struct msg_queue *msq)
 +static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq)
  {
 -      ipc_free_security(&msq->q_perm);
 +      ipc_free_security(msq);
  }
  
 -static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
 +static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
  
 -      isec = msq->q_perm.security;
 +      isec = msq->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = msq->q_perm.key;
 +      ad.u.ipc_id = msq->key;
  
 -      return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, SECCLASS_MSGQ,
                            MSGQ__ASSOCIATE, &ad);
  }
  
 -static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
 +static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
  {
        int err;
        int perms;
        case IPC_INFO:
        case MSG_INFO:
                /* No specific object, just general system-wide information. */
 -              return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case IPC_STAT:
        case MSG_STAT:
                return 0;
        }
  
 -      err = ipc_has_perm(&msq->q_perm, perms);
 +      err = ipc_has_perm(msq, perms);
        return err;
  }
  
 -static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg)
 +static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
  {
        struct ipc_security_struct *isec;
        struct msg_security_struct *msec;
        u32 sid = current_sid();
        int rc;
  
 -      isec = msq->q_perm.security;
 +      isec = msq->security;
        msec = msg->security;
  
        /*
                 * Compute new sid based on current process and
                 * message queue this message will be stored in
                 */
 -              rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
 -                                           NULL, &msec->sid);
 +              rc = security_transition_sid(&selinux_state, sid, isec->sid,
 +                                           SECCLASS_MSG, NULL, &msec->sid);
                if (rc)
                        return rc;
        }
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = msq->q_perm.key;
 +      ad.u.ipc_id = msq->key;
  
        /* Can this process write to the queue? */
 -      rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, SECCLASS_MSGQ,
                          MSGQ__WRITE, &ad);
        if (!rc)
                /* Can this process send the message */
 -              rc = avc_has_perm(sid, msec->sid, SECCLASS_MSG,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, msec->sid, SECCLASS_MSG,
                                  MSG__SEND, &ad);
        if (!rc)
                /* Can the message be put in the queue? */
 -              rc = avc_has_perm(msec->sid, isec->sid, SECCLASS_MSGQ,
 +              rc = avc_has_perm(&selinux_state,
 +                                msec->sid, isec->sid, SECCLASS_MSGQ,
                                  MSGQ__ENQUEUE, &ad);
  
        return rc;
  }
  
 -static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 +static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
                                    struct task_struct *target,
                                    long type, int mode)
  {
        u32 sid = task_sid(target);
        int rc;
  
 -      isec = msq->q_perm.security;
 +      isec = msq->security;
        msec = msg->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = msq->q_perm.key;
 +      ad.u.ipc_id = msq->key;
  
 -      rc = avc_has_perm(sid, isec->sid,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid,
                          SECCLASS_MSGQ, MSGQ__READ, &ad);
        if (!rc)
 -              rc = avc_has_perm(sid, msec->sid,
 +              rc = avc_has_perm(&selinux_state,
 +                                sid, msec->sid,
                                  SECCLASS_MSG, MSG__RECEIVE, &ad);
        return rc;
  }
  
  /* Shared Memory security operations */
 -static int selinux_shm_alloc_security(struct shmid_kernel *shp)
 +static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
  
 -      rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM);
 +      rc = ipc_alloc_security(shp, SECCLASS_SHM);
        if (rc)
                return rc;
  
 -      isec = shp->shm_perm.security;
 +      isec = shp->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = shp->shm_perm.key;
 +      ad.u.ipc_id = shp->key;
  
 -      rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, SECCLASS_SHM,
                          SHM__CREATE, &ad);
        if (rc) {
 -              ipc_free_security(&shp->shm_perm);
 +              ipc_free_security(shp);
                return rc;
        }
        return 0;
  }
  
 -static void selinux_shm_free_security(struct shmid_kernel *shp)
 +static void selinux_shm_free_security(struct kern_ipc_perm *shp)
  {
 -      ipc_free_security(&shp->shm_perm);
 +      ipc_free_security(shp);
  }
  
 -static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
 +static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
  
 -      isec = shp->shm_perm.security;
 +      isec = shp->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = shp->shm_perm.key;
 +      ad.u.ipc_id = shp->key;
  
 -      return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, SECCLASS_SHM,
                            SHM__ASSOCIATE, &ad);
  }
  
  /* Note, at this point, shp is locked down */
 -static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
 +static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
  {
        int perms;
        int err;
        case IPC_INFO:
        case SHM_INFO:
                /* No specific object, just general system-wide information. */
 -              return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case IPC_STAT:
        case SHM_STAT:
                return 0;
        }
  
 -      err = ipc_has_perm(&shp->shm_perm, perms);
 +      err = ipc_has_perm(shp, perms);
        return err;
  }
  
 -static int selinux_shm_shmat(struct shmid_kernel *shp,
 +static int selinux_shm_shmat(struct kern_ipc_perm *shp,
                             char __user *shmaddr, int shmflg)
  {
        u32 perms;
        else
                perms = SHM__READ | SHM__WRITE;
  
 -      return ipc_has_perm(&shp->shm_perm, perms);
 +      return ipc_has_perm(shp, perms);
  }
  
  /* Semaphore security operations */
 -static int selinux_sem_alloc_security(struct sem_array *sma)
 +static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
  
 -      rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM);
 +      rc = ipc_alloc_security(sma, SECCLASS_SEM);
        if (rc)
                return rc;
  
 -      isec = sma->sem_perm.security;
 +      isec = sma->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = sma->sem_perm.key;
 +      ad.u.ipc_id = sma->key;
  
 -      rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
 +      rc = avc_has_perm(&selinux_state,
 +                        sid, isec->sid, SECCLASS_SEM,
                          SEM__CREATE, &ad);
        if (rc) {
 -              ipc_free_security(&sma->sem_perm);
 +              ipc_free_security(sma);
                return rc;
        }
        return 0;
  }
  
 -static void selinux_sem_free_security(struct sem_array *sma)
 +static void selinux_sem_free_security(struct kern_ipc_perm *sma)
  {
 -      ipc_free_security(&sma->sem_perm);
 +      ipc_free_security(sma);
  }
  
 -static int selinux_sem_associate(struct sem_array *sma, int semflg)
 +static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
  {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
  
 -      isec = sma->sem_perm.security;
 +      isec = sma->security;
  
        ad.type = LSM_AUDIT_DATA_IPC;
 -      ad.u.ipc_id = sma->sem_perm.key;
 +      ad.u.ipc_id = sma->key;
  
 -      return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
 +      return avc_has_perm(&selinux_state,
 +                          sid, isec->sid, SECCLASS_SEM,
                            SEM__ASSOCIATE, &ad);
  }
  
  /* Note, at this point, sma is locked down */
 -static int selinux_sem_semctl(struct sem_array *sma, int cmd)
 +static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
  {
        int err;
        u32 perms;
        case IPC_INFO:
        case SEM_INFO:
                /* No specific object, just general system-wide information. */
 -              return avc_has_perm(current_sid(), SECINITSID_KERNEL,
 +              return avc_has_perm(&selinux_state,
 +                                  current_sid(), SECINITSID_KERNEL,
                                    SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
        case GETPID:
        case GETNCNT:
                return 0;
        }
  
 -      err = ipc_has_perm(&sma->sem_perm, perms);
 +      err = ipc_has_perm(sma, perms);
        return err;
  }
  
 -static int selinux_sem_semop(struct sem_array *sma,
 +static int selinux_sem_semop(struct kern_ipc_perm *sma,
                             struct sembuf *sops, unsigned nsops, int alter)
  {
        u32 perms;
        else
                perms = SEM__READ;
  
 -      return ipc_has_perm(&sma->sem_perm, perms);
 +      return ipc_has_perm(sma, perms);
  }
  
  static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
@@@ -6330,8 -5916,7 +6335,8 @@@ static int selinux_getprocattr(struct t
        __tsec = __task_cred(p)->security;
  
        if (current != p) {
 -              error = avc_has_perm(current_sid(), __tsec->sid,
 +              error = avc_has_perm(&selinux_state,
 +                                   current_sid(), __tsec->sid,
                                     SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
                if (error)
                        goto bad;
        if (!sid)
                return 0;
  
 -      error = security_sid_to_context(sid, value, &len);
 +      error = security_sid_to_context(&selinux_state, sid, value, &len);
        if (error)
                return error;
        return len;
@@@ -6380,24 -5965,19 +6385,24 @@@ static int selinux_setprocattr(const ch
         * Basic control over ability to set these attributes at all.
         */
        if (!strcmp(name, "exec"))
 -              error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETEXEC, NULL);
        else if (!strcmp(name, "fscreate"))
 -              error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETFSCREATE, NULL);
        else if (!strcmp(name, "keycreate"))
 -              error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETKEYCREATE, NULL);
        else if (!strcmp(name, "sockcreate"))
 -              error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETSOCKCREATE, NULL);
        else if (!strcmp(name, "current"))
 -              error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, mysid, SECCLASS_PROCESS,
                                     PROCESS__SETCURRENT, NULL);
        else
                error = -EINVAL;
                        str[size-1] = 0;
                        size--;
                }
 -              error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
 +              error = security_context_to_sid(&selinux_state, value, size,
 +                                              &sid, GFP_KERNEL);
                if (error == -EINVAL && !strcmp(name, "fscreate")) {
                        if (!has_cap_mac_admin(true)) {
                                struct audit_buffer *ab;
  
                                return error;
                        }
 -                      error = security_context_to_sid_force(value, size,
 -                                                            &sid);
 +                      error = security_context_to_sid_force(
 +                                                    &selinux_state,
 +                                                    value, size, &sid);
                }
                if (error)
                        return error;
        } else if (!strcmp(name, "fscreate")) {
                tsec->create_sid = sid;
        } else if (!strcmp(name, "keycreate")) {
 -              error = avc_has_perm(mysid, sid, SECCLASS_KEY, KEY__CREATE,
 +              error = avc_has_perm(&selinux_state,
 +                                   mysid, sid, SECCLASS_KEY, KEY__CREATE,
                                     NULL);
                if (error)
                        goto abort_change;
                /* Only allow single threaded processes to change context */
                error = -EPERM;
                if (!current_is_single_threaded()) {
 -                      error = security_bounded_transition(tsec->sid, sid);
 +                      error = security_bounded_transition(&selinux_state,
 +                                                          tsec->sid, sid);
                        if (error)
                                goto abort_change;
                }
  
                /* Check permissions for the transition. */
 -              error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
 +              error = avc_has_perm(&selinux_state,
 +                                   tsec->sid, sid, SECCLASS_PROCESS,
                                     PROCESS__DYNTRANSITION, NULL);
                if (error)
                        goto abort_change;
                   Otherwise, leave SID unchanged and fail. */
                ptsid = ptrace_parent_sid();
                if (ptsid != 0) {
 -                      error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
 +                      error = avc_has_perm(&selinux_state,
 +                                           ptsid, sid, SECCLASS_PROCESS,
                                             PROCESS__PTRACE, NULL);
                        if (error)
                                goto abort_change;
@@@ -6515,14 -6089,12 +6520,14 @@@ static int selinux_ismaclabel(const cha
  
  static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
  {
 -      return security_sid_to_context(secid, secdata, seclen);
 +      return security_sid_to_context(&selinux_state, secid,
 +                                     secdata, seclen);
  }
  
  static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
  {
 -      return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
 +      return security_context_to_sid(&selinux_state, secdata, seclen,
 +                                     secid, GFP_KERNEL);
  }
  
  static void selinux_release_secctx(char *secdata, u32 seclen)
@@@ -6614,8 -6186,7 +6619,8 @@@ static int selinux_key_permission(key_r
        key = key_ref_to_ptr(key_ref);
        ksec = key->security;
  
 -      return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
 +      return avc_has_perm(&selinux_state,
 +                          sid, ksec->sid, SECCLASS_KEY, perm, NULL);
  }
  
  static int selinux_key_getsecurity(struct key *key, char **_buffer)
        unsigned len;
        int rc;
  
 -      rc = security_sid_to_context(ksec->sid, &context, &len);
 +      rc = security_sid_to_context(&selinux_state, ksec->sid,
 +                                   &context, &len);
        if (!rc)
                rc = len;
        *_buffer = context;
@@@ -6651,8 -6221,7 +6656,8 @@@ static int selinux_ib_pkey_access(void 
        ibpkey.subnet_prefix = subnet_prefix;
        ibpkey.pkey = pkey_val;
        ad.u.ibpkey = &ibpkey;
 -      return avc_has_perm(sec->sid, sid,
 +      return avc_has_perm(&selinux_state,
 +                          sec->sid, sid,
                            SECCLASS_INFINIBAND_PKEY,
                            INFINIBAND_PKEY__ACCESS, &ad);
  }
@@@ -6666,8 -6235,7 +6671,8 @@@ static int selinux_ib_endport_manage_su
        struct ib_security_struct *sec = ib_sec;
        struct lsm_ibendport_audit ibendport;
  
 -      err = security_ib_endport_sid(dev_name, port_num, &sid);
 +      err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
 +                                    &sid);
  
        if (err)
                return err;
        strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
        ibendport.port = port_num;
        ad.u.ibendport = &ibendport;
 -      return avc_has_perm(sec->sid, sid,
 +      return avc_has_perm(&selinux_state,
 +                          sec->sid, sid,
                            SECCLASS_INFINIBAND_ENDPORT,
                            INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
  }
@@@ -6710,13 -6277,11 +6715,13 @@@ static int selinux_bpf(int cmd, union b
  
        switch (cmd) {
        case BPF_MAP_CREATE:
 -              ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
 +              ret = avc_has_perm(&selinux_state,
 +                                 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
                                   NULL);
                break;
        case BPF_PROG_LOAD:
 -              ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
 +              ret = avc_has_perm(&selinux_state,
 +                                 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
                                   NULL);
                break;
        default:
@@@ -6756,16 -6321,14 +6761,16 @@@ static int bpf_fd_pass(struct file *fil
        if (file->f_op == &bpf_map_fops) {
                map = file->private_data;
                bpfsec = map->security;
 -              ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
 +              ret = avc_has_perm(&selinux_state,
 +                                 sid, bpfsec->sid, SECCLASS_BPF,
                                   bpf_map_fmode_to_av(file->f_mode), NULL);
                if (ret)
                        return ret;
        } else if (file->f_op == &bpf_prog_fops) {
                prog = file->private_data;
                bpfsec = prog->aux->security;
 -              ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
 +              ret = avc_has_perm(&selinux_state,
 +                                 sid, bpfsec->sid, SECCLASS_BPF,
                                   BPF__PROG_RUN, NULL);
                if (ret)
                        return ret;
@@@ -6779,8 -6342,7 +6784,8 @@@ static int selinux_bpf_map(struct bpf_m
        struct bpf_security_struct *bpfsec;
  
        bpfsec = map->security;
 -      return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
 +      return avc_has_perm(&selinux_state,
 +                          sid, bpfsec->sid, SECCLASS_BPF,
                            bpf_map_fmode_to_av(fmode), NULL);
  }
  
@@@ -6790,8 -6352,7 +6795,8 @@@ static int selinux_bpf_prog(struct bpf_
        struct bpf_security_struct *bpfsec;
  
        bpfsec = prog->aux->security;
 -      return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
 +      return avc_has_perm(&selinux_state,
 +                          sid, bpfsec->sid, SECCLASS_BPF,
                            BPF__PROG_RUN, NULL);
  }
  
@@@ -6926,6 -6487,7 +6931,7 @@@ static struct security_hook_list selinu
        LSM_HOOK_INIT(cred_free, selinux_cred_free),
        LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
        LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
+       LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
        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(sk_clone_security, selinux_sk_clone_security),
        LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
        LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
 +      LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
 +      LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
 +      LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
        LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
        LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
        LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
@@@ -7088,12 -6647,6 +7094,12 @@@ static __init int selinux_init(void
  
        printk(KERN_INFO "SELinux:  Initializing.\n");
  
 +      memset(&selinux_state, 0, sizeof(selinux_state));
 +      enforcing_set(&selinux_state, selinux_enforcing_boot);
 +      selinux_state.checkreqprot = selinux_checkreqprot_boot;
 +      selinux_ss_init(&selinux_state.ss);
 +      selinux_avc_init(&selinux_state.avc);
 +
        /* Set the security state for the initial task. */
        cred_init_security();
  
                                            0, SLAB_PANIC, NULL);
        avc_init();
  
 +      avtab_cache_init();
 +
 +      ebitmap_cache_init();
 +
 +      hashtab_cache_init();
 +
        security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
  
        if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
        if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
                panic("SELinux: Unable to register AVC LSM notifier callback\n");
  
 -      if (selinux_enforcing)
 +      if (selinux_enforcing_boot)
                printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
        else
                printk(KERN_DEBUG "SELinux:  Starting in permissive mode\n");
@@@ -7242,22 -6789,23 +7248,22 @@@ static void selinux_nf_ip_exit(void
  #endif /* CONFIG_NETFILTER */
  
  #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 -static int selinux_disabled;
 -
 -int selinux_disable(void)
 +int selinux_disable(struct selinux_state *state)
  {
 -      if (ss_initialized) {
 +      if (state->initialized) {
                /* Not permitted after initial policy load. */
                return -EINVAL;
        }
  
 -      if (selinux_disabled) {
 +      if (state->disabled) {
                /* Only do this once. */
                return -EINVAL;
        }
  
 +      state->disabled = 1;
 +
        printk(KERN_INFO "SELinux:  Disabled at runtime.\n");
  
 -      selinux_disabled = 1;
        selinux_enabled = 0;
  
        security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
index 34e1e649f17515ca151cde820e9fac75f220e095,ed20d36c114913e76488b490f77face130d2ce22..73549007bf9e63d75920376b71671d5bd55ca3f0
@@@ -2049,6 -2049,23 +2049,23 @@@ static void smack_cred_transfer(struct 
        /* cbs copy rule list */
  }
  
+ /**
+  * smack_cred_getsecid - get the secid corresponding to a creds structure
+  * @c: the object creds
+  * @secid: where to put the result
+  *
+  * Sets the secid to contain a u32 version of the smack label.
+  */
+ static void smack_cred_getsecid(const struct cred *c, u32 *secid)
+ {
+       struct smack_known *skp;
+       rcu_read_lock();
+       skp = smk_of_task(c->security);
+       *secid = skp->smk_secid;
+       rcu_read_unlock();
+ }
  /**
   * smack_kernel_act_as - Set the subjective context in a set of credentials
   * @new: points to the set of credentials to be modified.
@@@ -2943,24 -2960,25 +2960,24 @@@ static void smack_msg_msg_free_security
  }
  
  /**
 - * smack_of_shm - the smack pointer for the shm
 - * @shp: the object
 + * smack_of_ipc - the smack pointer for the ipc
 + * @isp: the object
   *
   * Returns a pointer to the smack value
   */
 -static struct smack_known *smack_of_shm(struct shmid_kernel *shp)
 +static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
  {
 -      return (struct smack_known *)shp->shm_perm.security;
 +      return (struct smack_known *)isp->security;
  }
  
  /**
 - * smack_shm_alloc_security - Set the security blob for shm
 - * @shp: the object
 + * smack_ipc_alloc_security - Set the security blob for ipc
 + * @isp: the object
   *
   * Returns 0
   */
 -static int smack_shm_alloc_security(struct shmid_kernel *shp)
 +static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
  {
 -      struct kern_ipc_perm *isp = &shp->shm_perm;
        struct smack_known *skp = smk_of_current();
  
        isp->security = skp;
  }
  
  /**
 - * smack_shm_free_security - Clear the security blob for shm
 - * @shp: the object
 + * smack_ipc_free_security - Clear the security blob for ipc
 + * @isp: the object
   *
   * Clears the blob pointer
   */
 -static void smack_shm_free_security(struct shmid_kernel *shp)
 +static void smack_ipc_free_security(struct kern_ipc_perm *isp)
  {
 -      struct kern_ipc_perm *isp = &shp->shm_perm;
 -
        isp->security = NULL;
  }
  
  /**
   * smk_curacc_shm : check if current has access on shm
 - * @shp : the object
 + * @isp : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smk_curacc_shm(struct shmid_kernel *shp, int access)
 +static int smk_curacc_shm(struct kern_ipc_perm *isp, int access)
  {
 -      struct smack_known *ssp = smack_of_shm(shp);
 +      struct smack_known *ssp = smack_of_ipc(isp);
        struct smk_audit_info ad;
        int rc;
  
  #ifdef CONFIG_AUDIT
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
 -      ad.a.u.ipc_id = shp->shm_perm.id;
 +      ad.a.u.ipc_id = isp->id;
  #endif
        rc = smk_curacc(ssp, access, &ad);
        rc = smk_bu_current("shm", ssp, access, rc);
  
  /**
   * smack_shm_associate - Smack access check for shm
 - * @shp: the object
 + * @isp: the object
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
 +static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg)
  {
        int may;
  
        may = smack_flags_to_may(shmflg);
 -      return smk_curacc_shm(shp, may);
 +      return smk_curacc_shm(isp, may);
  }
  
  /**
   * smack_shm_shmctl - Smack access check for shm
 - * @shp: the object
 + * @isp: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
 +static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd)
  {
        int may;
  
        default:
                return -EINVAL;
        }
 -      return smk_curacc_shm(shp, may);
 +      return smk_curacc_shm(isp, may);
  }
  
  /**
   * smack_shm_shmat - Smack access for shmat
 - * @shp: the object
 + * @isp: the object
   * @shmaddr: unused
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
 +static int smack_shm_shmat(struct kern_ipc_perm *ipc, char __user *shmaddr,
                           int shmflg)
  {
        int may;
  
        may = smack_flags_to_may(shmflg);
 -      return smk_curacc_shm(shp, may);
 -}
 -
 -/**
 - * smack_of_sem - the smack pointer for the sem
 - * @sma: the object
 - *
 - * Returns a pointer to the smack value
 - */
 -static struct smack_known *smack_of_sem(struct sem_array *sma)
 -{
 -      return (struct smack_known *)sma->sem_perm.security;
 -}
 -
 -/**
 - * smack_sem_alloc_security - Set the security blob for sem
 - * @sma: the object
 - *
 - * Returns 0
 - */
 -static int smack_sem_alloc_security(struct sem_array *sma)
 -{
 -      struct kern_ipc_perm *isp = &sma->sem_perm;
 -      struct smack_known *skp = smk_of_current();
 -
 -      isp->security = skp;
 -      return 0;
 -}
 -
 -/**
 - * smack_sem_free_security - Clear the security blob for sem
 - * @sma: the object
 - *
 - * Clears the blob pointer
 - */
 -static void smack_sem_free_security(struct sem_array *sma)
 -{
 -      struct kern_ipc_perm *isp = &sma->sem_perm;
 -
 -      isp->security = NULL;
 +      return smk_curacc_shm(ipc, may);
  }
  
  /**
   * smk_curacc_sem : check if current has access on sem
 - * @sma : the object
 + * @isp : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smk_curacc_sem(struct sem_array *sma, int access)
 +static int smk_curacc_sem(struct kern_ipc_perm *isp, int access)
  {
 -      struct smack_known *ssp = smack_of_sem(sma);
 +      struct smack_known *ssp = smack_of_ipc(isp);
        struct smk_audit_info ad;
        int rc;
  
  #ifdef CONFIG_AUDIT
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
 -      ad.a.u.ipc_id = sma->sem_perm.id;
 +      ad.a.u.ipc_id = isp->id;
  #endif
        rc = smk_curacc(ssp, access, &ad);
        rc = smk_bu_current("sem", ssp, access, rc);
  
  /**
   * smack_sem_associate - Smack access check for sem
 - * @sma: the object
 + * @isp: the object
   * @semflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_sem_associate(struct sem_array *sma, int semflg)
 +static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg)
  {
        int may;
  
        may = smack_flags_to_may(semflg);
 -      return smk_curacc_sem(sma, may);
 +      return smk_curacc_sem(isp, may);
  }
  
  /**
   * smack_sem_shmctl - Smack access check for sem
 - * @sma: the object
 + * @isp: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_sem_semctl(struct sem_array *sma, int cmd)
 +static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd)
  {
        int may;
  
                return -EINVAL;
        }
  
 -      return smk_curacc_sem(sma, may);
 +      return smk_curacc_sem(isp, may);
  }
  
  /**
   * smack_sem_semop - Smack checks of semaphore operations
 - * @sma: the object
 + * @isp: the object
   * @sops: unused
   * @nsops: unused
   * @alter: unused
   *
   * Returns 0 if access is allowed, error code otherwise
   */
 -static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
 +static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops,
                           unsigned nsops, int alter)
  {
 -      return smk_curacc_sem(sma, MAY_READWRITE);
 -}
 -
 -/**
 - * smack_msg_alloc_security - Set the security blob for msg
 - * @msq: the object
 - *
 - * Returns 0
 - */
 -static int smack_msg_queue_alloc_security(struct msg_queue *msq)
 -{
 -      struct kern_ipc_perm *kisp = &msq->q_perm;
 -      struct smack_known *skp = smk_of_current();
 -
 -      kisp->security = skp;
 -      return 0;
 -}
 -
 -/**
 - * smack_msg_free_security - Clear the security blob for msg
 - * @msq: the object
 - *
 - * Clears the blob pointer
 - */
 -static void smack_msg_queue_free_security(struct msg_queue *msq)
 -{
 -      struct kern_ipc_perm *kisp = &msq->q_perm;
 -
 -      kisp->security = NULL;
 -}
 -
 -/**
 - * smack_of_msq - the smack pointer for the msq
 - * @msq: the object
 - *
 - * Returns a pointer to the smack label entry
 - */
 -static struct smack_known *smack_of_msq(struct msg_queue *msq)
 -{
 -      return (struct smack_known *)msq->q_perm.security;
 +      return smk_curacc_sem(isp, MAY_READWRITE);
  }
  
  /**
   * smk_curacc_msq : helper to check if current has access on msq
 - * @msq : the msq
 + * @isp : the msq
   * @access : access requested
   *
   * return 0 if current has access, error otherwise
   */
 -static int smk_curacc_msq(struct msg_queue *msq, int access)
 +static int smk_curacc_msq(struct kern_ipc_perm *isp, int access)
  {
 -      struct smack_known *msp = smack_of_msq(msq);
 +      struct smack_known *msp = smack_of_ipc(isp);
        struct smk_audit_info ad;
        int rc;
  
  #ifdef CONFIG_AUDIT
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
 -      ad.a.u.ipc_id = msq->q_perm.id;
 +      ad.a.u.ipc_id = isp->id;
  #endif
        rc = smk_curacc(msp, access, &ad);
        rc = smk_bu_current("msq", msp, access, rc);
  
  /**
   * smack_msg_queue_associate - Smack access check for msg_queue
 - * @msq: the object
 + * @isp: the object
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
 +static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg)
  {
        int may;
  
        may = smack_flags_to_may(msqflg);
 -      return smk_curacc_msq(msq, may);
 +      return smk_curacc_msq(isp, may);
  }
  
  /**
   * smack_msg_queue_msgctl - Smack access check for msg_queue
 - * @msq: the object
 + * @isp: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
 +static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd)
  {
        int may;
  
                return -EINVAL;
        }
  
 -      return smk_curacc_msq(msq, may);
 +      return smk_curacc_msq(isp, may);
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
 - * @msq: the object
 + * @isp: the object
   * @msg: unused
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
 -static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
 +static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg,
                                  int msqflg)
  {
        int may;
  
        may = smack_flags_to_may(msqflg);
 -      return smk_curacc_msq(msq, may);
 +      return smk_curacc_msq(isp, may);
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
 - * @msq: the object
 + * @isp: the object
   * @msg: unused
   * @target: unused
   * @type: unused
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
 -static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 +static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg,
                        struct task_struct *target, long type, int mode)
  {
 -      return smk_curacc_msq(msq, MAY_READWRITE);
 +      return smk_curacc_msq(isp, MAY_READWRITE);
  }
  
  /**
@@@ -3348,7 -3446,6 +3365,7 @@@ static void smack_d_instantiate(struct 
        if (opt_dentry->d_parent == opt_dentry) {
                switch (sbp->s_magic) {
                case CGROUP_SUPER_MAGIC:
 +              case CGROUP2_SUPER_MAGIC:
                        /*
                         * The cgroup filesystem is never mounted,
                         * so there's no opportunity to set the mount
        switch (sbp->s_magic) {
        case SMACK_MAGIC:
        case CGROUP_SUPER_MAGIC:
 +      case CGROUP2_SUPER_MAGIC:
                /*
                 * Casey says that it's a little embarrassing
                 * that the smack file system doesn't do
@@@ -4654,6 -4750,7 +4671,7 @@@ static struct security_hook_list smack_
        LSM_HOOK_INIT(cred_free, smack_cred_free),
        LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
        LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
+       LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
        LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
        LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
        LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
        LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
        LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security),
  
 -      LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security),
 -      LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security),
 +      LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security),
 +      LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security),
        LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
        LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
        LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
        LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
  
 -      LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security),
 -      LSM_HOOK_INIT(shm_free_security, smack_shm_free_security),
 +      LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security),
 +      LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security),
        LSM_HOOK_INIT(shm_associate, smack_shm_associate),
        LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
        LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
  
 -      LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security),
 -      LSM_HOOK_INIT(sem_free_security, smack_sem_free_security),
 +      LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security),
 +      LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security),
        LSM_HOOK_INIT(sem_associate, smack_sem_associate),
        LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
        LSM_HOOK_INIT(sem_semop, smack_sem_semop),
This page took 0.297457 seconds and 4 git commands to generate.