Commit 9f9310bf authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20240105' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:

 - Add a new SELinux initial SID, SECINITSID_INIT, to represent
   userspace processes started before the SELinux policy is loaded in
   early boot.

   Prior to this patch all processes were marked as SECINITSID_KERNEL
   before the SELinux policy was loaded, making it difficult to
   distinquish early boot userspace processes from the kernel in the
   SELinux policy.

   For most users this will be a non-issue as the policy is loaded early
   enough during boot, but for users who load their SELinux policy
   relatively late, this should make it easier to construct meaningful
   security policies.

 - Cleanups to the selinuxfs code by Al, mostly on VFS related issues
   during a policy reload.

   The commit description has more detail, but the quick summary is that
   we are replacing a disconnected directory approach with a temporary
   directory that we swapover at the end of the reload.

 - Fix an issue where the input sanity checking on socket bind()
   operations was slightly different depending on the presence of
   SELinux.

   This is caused by the placement of the LSM hooks in the generic
   socket layer as opposed to the protocol specific bind() handler where
   the protocol specific sanity checks are performed. Mickaël has
   mentioned that he is working to fix this, but in the meantime we just
   ensure that we are replicating the checks properly.

   We need to balance the placement of the LSM hooks with the number of
   LSM hooks; pushing the hooks down into the protocol layers is likely
   not the right answer.

 - Update the avc_has_perm_noaudit() prototype to better match the
   function definition.

 - Migrate from using partial_name_hash() to full_name_hash() the
   filename transition hash table.

   This improves the quality of the code and has the potential for a
   minor performance bump.

 - Consolidate some open coded SELinux access vector comparisions into a
   single new function, avtab_node_cmp(), and use that instead.

   A small, but nice win for code quality and maintainability.

 - Updated the SELinux MAINTAINERS entry with additional information
   around process, bug reporting, etc.

   We're also updating some of our "official" roles: dropping Eric Paris
   and adding Ondrej as a reviewer.

 - Cleanup the coding style crimes in security/selinux/include.

   While I'm not a fan of code churn, I am pushing for more automated
   code checks that can be done at the developer level and one of the
   obvious things to check for is coding style.

   In an effort to start from a "good" base I'm slowly working through
   our source files cleaning them up with the help of clang-format and
   good ol' fashioned human eyeballs; this has the first batch of these
   changes.

   I've been splitting the changes up per-file to help reduce the impact
   if backports are required (either for LTS or distro kernels), and I
   expect the some of the larger files, e.g. hooks.c and ss/services.c,
   will likely need to be split even further.

 - Cleanup old, outdated comments.

* tag 'selinux-pr-20240105' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (24 commits)
  selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket
  selinux: fix style issues in security/selinux/include/initial_sid_to_string.h
  selinux: fix style issues in security/selinux/include/xfrm.h
  selinux: fix style issues in security/selinux/include/security.h
  selinux: fix style issues with security/selinux/include/policycap_names.h
  selinux: fix style issues in security/selinux/include/policycap.h
  selinux: fix style issues in security/selinux/include/objsec.h
  selinux: fix style issues with security/selinux/include/netlabel.h
  selinux: fix style issues in security/selinux/include/netif.h
  selinux: fix style issues in security/selinux/include/ima.h
  selinux: fix style issues in security/selinux/include/conditional.h
  selinux: fix style issues in security/selinux/include/classmap.h
  selinux: fix style issues in security/selinux/include/avc_ss.h
  selinux: align avc_has_perm_noaudit() prototype with definition
  selinux: fix style issues in security/selinux/include/avc.h
  selinux: fix style issues in security/selinux/include/audit.h
  MAINTAINERS: drop Eric Paris from his SELinux role
  MAINTAINERS: add Ondrej Mosnacek as a SELinux reviewer
  selinux: remove the wrong comment about multithreaded process handling
  selinux: introduce an initial SID for early boot processes
  ...
parents eab23bc8 bbf5a1d0
...@@ -19465,12 +19465,14 @@ X: security/selinux/ ...@@ -19465,12 +19465,14 @@ X: security/selinux/
SELINUX SECURITY MODULE SELINUX SECURITY MODULE
M: Paul Moore <paul@paul-moore.com> M: Paul Moore <paul@paul-moore.com>
M: Stephen Smalley <stephen.smalley.work@gmail.com> M: Stephen Smalley <stephen.smalley.work@gmail.com>
M: Eric Paris <eparis@parisplace.org> R: Ondrej Mosnacek <omosnace@redhat.com>
L: selinux@vger.kernel.org L: selinux@vger.kernel.org
S: Supported S: Supported
W: https://selinuxproject.org
W: https://github.com/SELinuxProject W: https://github.com/SELinuxProject
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git Q: https://patchwork.kernel.org/project/selinux/list
B: mailto:selinux@vger.kernel.org
P: https://github.com/SELinuxProject/selinux-kernel/blob/main/README.md
T: git https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
F: Documentation/ABI/removed/sysfs-selinux-checkreqprot F: Documentation/ABI/removed/sysfs-selinux-checkreqprot
F: Documentation/ABI/removed/sysfs-selinux-disable F: Documentation/ABI/removed/sysfs-selinux-disable
F: Documentation/admin-guide/LSM/SELinux.rst F: Documentation/admin-guide/LSM/SELinux.rst
......
...@@ -2313,6 +2313,19 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) ...@@ -2313,6 +2313,19 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
new_tsec->keycreate_sid = 0; new_tsec->keycreate_sid = 0;
new_tsec->sockcreate_sid = 0; new_tsec->sockcreate_sid = 0;
/*
* Before policy is loaded, label any task outside kernel space
* as SECINITSID_INIT, so that any userspace tasks surviving from
* early boot end up with a label different from SECINITSID_KERNEL
* (if the policy chooses to set SECINITSID_INIT != SECINITSID_KERNEL).
*/
if (!selinux_initialized()) {
new_tsec->sid = SECINITSID_INIT;
/* also clear the exec_sid just in case */
new_tsec->exec_sid = 0;
return 0;
}
if (old_tsec->exec_sid) { if (old_tsec->exec_sid) {
new_tsec->sid = old_tsec->exec_sid; new_tsec->sid = old_tsec->exec_sid;
/* Reset exec SID on execve. */ /* Reset exec SID on execve. */
...@@ -4547,6 +4560,21 @@ static int sock_has_perm(struct sock *sk, u32 perms) ...@@ -4547,6 +4560,21 @@ static int sock_has_perm(struct sock *sk, u32 perms)
if (sksec->sid == SECINITSID_KERNEL) if (sksec->sid == SECINITSID_KERNEL)
return 0; return 0;
/*
* Before POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, sockets that
* inherited the kernel context from early boot used to be skipped
* here, so preserve that behavior unless the capability is set.
*
* By setting the capability the policy signals that it is ready
* for this quirk to be fixed. Note that sockets created by a kernel
* thread or a usermode helper executed without a transition will
* still be skipped in this check regardless of the policycap
* setting.
*/
if (!selinux_policycap_userspace_initial_context() &&
sksec->sid == SECINITSID_INIT)
return 0;
ad_net_init_from_sk(&ad, &net, sk); ad_net_init_from_sk(&ad, &net, sk);
return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms, return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
...@@ -4661,6 +4689,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -4661,6 +4689,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
return -EINVAL; return -EINVAL;
addr4 = (struct sockaddr_in *)address; addr4 = (struct sockaddr_in *)address;
if (family_sa == AF_UNSPEC) { if (family_sa == AF_UNSPEC) {
if (family == PF_INET6) {
/* Length check from inet6_bind_sk() */
if (addrlen < SIN6_LEN_RFC2133)
return -EINVAL;
/* Family check from __inet6_bind() */
goto err_af;
}
/* see __inet_bind(), we only want to allow /* see __inet_bind(), we only want to allow
* AF_UNSPEC if the address is INADDR_ANY * AF_UNSPEC if the address is INADDR_ANY
*/ */
...@@ -6425,7 +6460,6 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) ...@@ -6425,7 +6460,6 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
if (sid == 0) if (sid == 0)
goto abort_change; goto abort_change;
/* Only allow single threaded processes to change context */
if (!current_is_single_threaded()) { if (!current_is_single_threaded()) {
error = security_bounded_transition(tsec->sid, sid); error = security_bounded_transition(tsec->sid, sid);
if (error) if (error)
......
...@@ -57,4 +57,3 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule); ...@@ -57,4 +57,3 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
int selinux_audit_rule_known(struct audit_krule *rule); int selinux_audit_rule_known(struct audit_krule *rule);
#endif /* _SELINUX_AUDIT_H */ #endif /* _SELINUX_AUDIT_H */
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
* Author : Stephen Smalley, <stephen.smalley.work@gmail.com> * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/ */
#ifndef _SELINUX_AVC_H_ #ifndef _SELINUX_AVC_H_
#define _SELINUX_AVC_H_ #define _SELINUX_AVC_H_
...@@ -60,11 +61,8 @@ struct selinux_audit_data { ...@@ -60,11 +61,8 @@ struct selinux_audit_data {
void __init avc_init(void); void __init avc_init(void);
static inline u32 avc_audit_required(u32 requested, static inline u32 avc_audit_required(u32 requested, struct av_decision *avd,
struct av_decision *avd, int result, u32 auditdeny, u32 *deniedp)
int result,
u32 auditdeny,
u32 *deniedp)
{ {
u32 denied, audited; u32 denied, audited;
denied = requested & ~avd->allowed; denied = requested & ~avd->allowed;
...@@ -96,9 +94,8 @@ static inline u32 avc_audit_required(u32 requested, ...@@ -96,9 +94,8 @@ static inline u32 avc_audit_required(u32 requested,
return audited; return audited;
} }
int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited,
u32 requested, u32 audited, u32 denied, int result, u32 denied, int result, struct common_audit_data *a);
struct common_audit_data *a);
/** /**
* avc_audit - Audit the granting or denial of permissions. * avc_audit - Audit the granting or denial of permissions.
...@@ -119,36 +116,29 @@ int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, ...@@ -119,36 +116,29 @@ int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
* be performed under a lock, to allow the lock to be released * be performed under a lock, to allow the lock to be released
* before calling the auditing code. * before calling the auditing code.
*/ */
static inline int avc_audit(u32 ssid, u32 tsid, static inline int avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u16 tclass, u32 requested, struct av_decision *avd, int result,
struct av_decision *avd,
int result,
struct common_audit_data *a) struct common_audit_data *a)
{ {
u32 audited, denied; u32 audited, denied;
audited = avc_audit_required(requested, avd, result, 0, &denied); audited = avc_audit_required(requested, avd, result, 0, &denied);
if (likely(!audited)) if (likely(!audited))
return 0; return 0;
return slow_avc_audit(ssid, tsid, tclass, return slow_avc_audit(ssid, tsid, tclass, requested, audited, denied,
requested, audited, denied, result, result, a);
a);
} }
#define AVC_STRICT 1 /* Ignore permissive mode. */ #define AVC_STRICT 1 /* Ignore permissive mode. */
#define AVC_EXTENDED_PERMS 2 /* update extended permissions */ #define AVC_EXTENDED_PERMS 2 /* update extended permissions */
int avc_has_perm_noaudit(u32 ssid, u32 tsid, int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u16 tclass, u32 requested, unsigned int flags, struct av_decision *avd);
unsigned flags,
struct av_decision *avd);
int avc_has_perm(u32 ssid, u32 tsid, int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u16 tclass, u32 requested,
struct common_audit_data *auditdata); struct common_audit_data *auditdata);
int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u8 driver, u8 perm, struct common_audit_data *ad); u8 driver, u8 perm, struct common_audit_data *ad);
u32 avc_policy_seqno(void); u32 avc_policy_seqno(void);
#define AVC_CALLBACK_GRANT 1 #define AVC_CALLBACK_GRANT 1
...@@ -156,7 +146,7 @@ u32 avc_policy_seqno(void); ...@@ -156,7 +146,7 @@ u32 avc_policy_seqno(void);
#define AVC_CALLBACK_REVOKE 4 #define AVC_CALLBACK_REVOKE 4
#define AVC_CALLBACK_RESET 8 #define AVC_CALLBACK_RESET 8
#define AVC_CALLBACK_AUDITALLOW_ENABLE 16 #define AVC_CALLBACK_AUDITALLOW_ENABLE 16
#define AVC_CALLBACK_AUDITALLOW_DISABLE 32 #define AVC_CALLBACK_AUDITALLOW_DISABLE 32
#define AVC_CALLBACK_AUDITDENY_ENABLE 64 #define AVC_CALLBACK_AUDITDENY_ENABLE 64
#define AVC_CALLBACK_AUDITDENY_DISABLE 128 #define AVC_CALLBACK_AUDITDENY_DISABLE 128
#define AVC_CALLBACK_ADD_XPERMS 256 #define AVC_CALLBACK_ADD_XPERMS 256
...@@ -173,4 +163,3 @@ DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); ...@@ -173,4 +163,3 @@ DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
#endif #endif
#endif /* _SELINUX_AVC_H_ */ #endif /* _SELINUX_AVC_H_ */
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
* Author : Stephen Smalley, <stephen.smalley.work@gmail.com> * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/ */
#ifndef _SELINUX_AVC_SS_H_ #ifndef _SELINUX_AVC_SS_H_
#define _SELINUX_AVC_SS_H_ #define _SELINUX_AVC_SS_H_
...@@ -20,4 +21,3 @@ struct security_class_mapping { ...@@ -20,4 +21,3 @@ struct security_class_mapping {
extern const struct security_class_mapping secclass_map[]; extern const struct security_class_mapping secclass_map[];
#endif /* _SELINUX_AVC_SS_H_ */ #endif /* _SELINUX_AVC_SS_H_ */
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/socket.h> #include <linux/socket.h>
#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ #define COMMON_FILE_SOCK_PERMS \
"getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map" "ioctl", "read", "write", "create", "getattr", "setattr", "lock", \
"relabelfrom", "relabelto", "append", "map"
#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ #define COMMON_FILE_PERMS \
"rename", "execute", "quotaon", "mounton", "audit_access", \ COMMON_FILE_SOCK_PERMS, "unlink", "link", "rename", "execute", \
"open", "execmod", "watch", "watch_mount", "watch_sb", \ "quotaon", "mounton", "audit_access", "open", "execmod", \
"watch_with_perm", "watch_reads" "watch", "watch_mount", "watch_sb", "watch_with_perm", \
"watch_reads"
#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ #define COMMON_SOCK_PERMS \
"listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ COMMON_FILE_SOCK_PERMS, "bind", "connect", "listen", "accept", \
"sendto", "name_bind" "getopt", "setopt", "shutdown", "recvfrom", "sendto", \
"name_bind"
#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ #define COMMON_IPC_PERMS \
"write", "associate", "unix_read", "unix_write" "create", "destroy", "getattr", "setattr", "read", "write", \
"associate", "unix_read", "unix_write"
#define COMMON_CAP_PERMS "chown", "dac_override", "dac_read_search", \ #define COMMON_CAP_PERMS \
"fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", \ "chown", "dac_override", "dac_read_search", "fowner", "fsetid", \
"linux_immutable", "net_bind_service", "net_broadcast", \ "kill", "setgid", "setuid", "setpcap", "linux_immutable", \
"net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", \ "net_bind_service", "net_broadcast", "net_admin", "net_raw", \
"sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \ "ipc_lock", "ipc_owner", "sys_module", "sys_rawio", \
"sys_boot", "sys_nice", "sys_resource", "sys_time", \ "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \
"sys_tty_config", "mknod", "lease", "audit_write", \ "sys_boot", "sys_nice", "sys_resource", "sys_time", \
"audit_control", "setfcap" "sys_tty_config", "mknod", "lease", "audit_write", \
"audit_control", "setfcap"
#define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \ #define COMMON_CAP2_PERMS \
"wake_alarm", "block_suspend", "audit_read", "perfmon", "bpf", \ "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", \
"checkpoint_restore" "audit_read", "perfmon", "bpf", "checkpoint_restore"
#if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE #if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE
#error New capability defined, please update COMMON_CAP2_PERMS. #error New capability defined, please update COMMON_CAP2_PERMS.
...@@ -40,224 +46,140 @@ ...@@ -40,224 +46,140 @@
*/ */
const struct security_class_mapping secclass_map[] = { const struct security_class_mapping secclass_map[] = {
{ "security", { "security",
{ "compute_av", "compute_create", "compute_member", { "compute_av", "compute_create", "compute_member", "check_context",
"check_context", "load_policy", "compute_relabel", "load_policy", "compute_relabel", "compute_user", "setenforce",
"compute_user", "setenforce", "setbool", "setsecparam", "setbool", "setsecparam", "setcheckreqprot", "read_policy",
"setcheckreqprot", "read_policy", "validate_trans", NULL } }, "validate_trans", NULL } },
{ "process", { "process",
{ "fork", "transition", "sigchld", "sigkill", { "fork", "transition", "sigchld", "sigkill",
"sigstop", "signull", "signal", "ptrace", "getsched", "setsched", "sigstop", "signull", "signal", "ptrace",
"getsession", "getpgid", "setpgid", "getcap", "setcap", "share", "getsched", "setsched", "getsession", "getpgid",
"getattr", "setexec", "setfscreate", "noatsecure", "siginh", "setpgid", "getcap", "setcap", "share",
"setrlimit", "rlimitinh", "dyntransition", "setcurrent", "getattr", "setexec", "setfscreate", "noatsecure",
"execmem", "execstack", "execheap", "setkeycreate", "siginh", "setrlimit", "rlimitinh", "dyntransition",
"setsockcreate", "getrlimit", NULL } }, "setcurrent", "execmem", "execstack", "execheap",
{ "process2", "setkeycreate", "setsockcreate", "getrlimit", NULL } },
{ "nnp_transition", "nosuid_transition", NULL } }, { "process2", { "nnp_transition", "nosuid_transition", NULL } },
{ "system", { "system",
{ "ipc_info", "syslog_read", "syslog_mod", { "ipc_info", "syslog_read", "syslog_mod", "syslog_console",
"syslog_console", "module_request", "module_load", NULL } }, "module_request", "module_load", NULL } },
{ "capability", { "capability", { COMMON_CAP_PERMS, NULL } },
{ COMMON_CAP_PERMS, NULL } },
{ "filesystem", { "filesystem",
{ "mount", "remount", "unmount", "getattr", { "mount", "remount", "unmount", "getattr", "relabelfrom",
"relabelfrom", "relabelto", "associate", "quotamod", "relabelto", "associate", "quotamod", "quotaget", "watch", NULL } },
"quotaget", "watch", NULL } },
{ "file", { "file",
{ COMMON_FILE_PERMS, { COMMON_FILE_PERMS, "execute_no_trans", "entrypoint", NULL } },
"execute_no_trans", "entrypoint", NULL } },
{ "dir", { "dir",
{ COMMON_FILE_PERMS, "add_name", "remove_name", { COMMON_FILE_PERMS, "add_name", "remove_name", "reparent", "search",
"reparent", "search", "rmdir", NULL } }, "rmdir", NULL } },
{ "fd", { "use", NULL } }, { "fd", { "use", NULL } },
{ "lnk_file", { "lnk_file", { COMMON_FILE_PERMS, NULL } },
{ COMMON_FILE_PERMS, NULL } }, { "chr_file", { COMMON_FILE_PERMS, NULL } },
{ "chr_file", { "blk_file", { COMMON_FILE_PERMS, NULL } },
{ COMMON_FILE_PERMS, NULL } }, { "sock_file", { COMMON_FILE_PERMS, NULL } },
{ "blk_file", { "fifo_file", { COMMON_FILE_PERMS, NULL } },
{ COMMON_FILE_PERMS, NULL } }, { "socket", { COMMON_SOCK_PERMS, NULL } },
{ "sock_file",
{ COMMON_FILE_PERMS, NULL } },
{ "fifo_file",
{ COMMON_FILE_PERMS, NULL } },
{ "socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "tcp_socket", { "tcp_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "node_bind", "name_connect", NULL } },
"node_bind", "name_connect", { "udp_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } },
NULL } }, { "rawip_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } },
{ "udp_socket", { "node", { "recvfrom", "sendto", NULL } },
{ COMMON_SOCK_PERMS, { "netif", { "ingress", "egress", NULL } },
"node_bind", NULL } }, { "netlink_socket", { COMMON_SOCK_PERMS, NULL } },
{ "rawip_socket", { "packet_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, { "key_socket", { COMMON_SOCK_PERMS, NULL } },
"node_bind", NULL } }, { "unix_stream_socket", { COMMON_SOCK_PERMS, "connectto", NULL } },
{ "node", { "unix_dgram_socket", { COMMON_SOCK_PERMS, NULL } },
{ "recvfrom", "sendto", NULL } }, { "sem", { COMMON_IPC_PERMS, NULL } },
{ "netif",
{ "ingress", "egress", NULL } },
{ "netlink_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "packet_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "key_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "unix_stream_socket",
{ COMMON_SOCK_PERMS, "connectto", NULL } },
{ "unix_dgram_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "sem",
{ COMMON_IPC_PERMS, NULL } },
{ "msg", { "send", "receive", NULL } }, { "msg", { "send", "receive", NULL } },
{ "msgq", { "msgq", { COMMON_IPC_PERMS, "enqueue", NULL } },
{ COMMON_IPC_PERMS, "enqueue", NULL } }, { "shm", { COMMON_IPC_PERMS, "lock", NULL } },
{ "shm", { "ipc", { COMMON_IPC_PERMS, NULL } },
{ COMMON_IPC_PERMS, "lock", NULL } },
{ "ipc",
{ COMMON_IPC_PERMS, NULL } },
{ "netlink_route_socket", { "netlink_route_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } },
"nlmsg_read", "nlmsg_write", NULL } },
{ "netlink_tcpdiag_socket", { "netlink_tcpdiag_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } },
"nlmsg_read", "nlmsg_write", NULL } }, { "netlink_nflog_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_nflog_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_xfrm_socket", { "netlink_xfrm_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } },
"nlmsg_read", "nlmsg_write", NULL } }, { "netlink_selinux_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_selinux_socket", { "netlink_iscsi_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_iscsi_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_audit_socket", { "netlink_audit_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", "nlmsg_relay",
"nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv", "nlmsg_readpriv", "nlmsg_tty_audit", NULL } },
"nlmsg_tty_audit", NULL } }, { "netlink_fib_lookup_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_fib_lookup_socket", { "netlink_connector_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "netlink_netfilter_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_connector_socket", { "netlink_dnrt_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_netfilter_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_dnrt_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "association", { "association",
{ "sendto", "recvfrom", "setcontext", "polmatch", NULL } }, { "sendto", "recvfrom", "setcontext", "polmatch", NULL } },
{ "netlink_kobject_uevent_socket", { "netlink_kobject_uevent_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "netlink_generic_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_generic_socket", { "netlink_scsitransport_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "netlink_rdma_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_scsitransport_socket", { "netlink_crypto_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "appletalk_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netlink_rdma_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "netlink_crypto_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "appletalk_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "packet", { "packet",
{ "send", "recv", "relabelto", "forward_in", "forward_out", NULL } }, { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
{ "key", { "key",
{ "view", "read", "write", "search", "link", "setattr", "create", { "view", "read", "write", "search", "link", "setattr", "create",
NULL } }, NULL } },
{ "dccp_socket", { "dccp_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "node_bind", "name_connect", NULL } },
"node_bind", "name_connect", NULL } },
{ "memprotect", { "mmap_zero", NULL } }, { "memprotect", { "mmap_zero", NULL } },
{ "peer", { "recv", NULL } }, { "peer", { "recv", NULL } },
{ "capability2", { "capability2", { COMMON_CAP2_PERMS, NULL } },
{ COMMON_CAP2_PERMS, NULL } },
{ "kernel_service", { "use_as_override", "create_files_as", NULL } }, { "kernel_service", { "use_as_override", "create_files_as", NULL } },
{ "tun_socket", { "tun_socket", { COMMON_SOCK_PERMS, "attach_queue", NULL } },
{ COMMON_SOCK_PERMS, "attach_queue", NULL } }, { "binder",
{ "binder", { "impersonate", "call", "set_context_mgr", "transfer", { "impersonate", "call", "set_context_mgr", "transfer", NULL } },
NULL } }, { "cap_userns", { COMMON_CAP_PERMS, NULL } },
{ "cap_userns", { "cap2_userns", { COMMON_CAP2_PERMS, NULL } },
{ COMMON_CAP_PERMS, NULL } },
{ "cap2_userns",
{ COMMON_CAP2_PERMS, NULL } },
{ "sctp_socket", { "sctp_socket",
{ COMMON_SOCK_PERMS, { COMMON_SOCK_PERMS, "node_bind", "name_connect", "association",
"node_bind", "name_connect", "association", NULL } }, NULL } },
{ "icmp_socket", { "icmp_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } },
{ COMMON_SOCK_PERMS, { "ax25_socket", { COMMON_SOCK_PERMS, NULL } },
"node_bind", NULL } }, { "ipx_socket", { COMMON_SOCK_PERMS, NULL } },
{ "ax25_socket", { "netrom_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "atmpvc_socket", { COMMON_SOCK_PERMS, NULL } },
{ "ipx_socket", { "x25_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "rose_socket", { COMMON_SOCK_PERMS, NULL } },
{ "netrom_socket", { "decnet_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "atmsvc_socket", { COMMON_SOCK_PERMS, NULL } },
{ "atmpvc_socket", { "rds_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "irda_socket", { COMMON_SOCK_PERMS, NULL } },
{ "x25_socket", { "pppox_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "llc_socket", { COMMON_SOCK_PERMS, NULL } },
{ "rose_socket", { "can_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "tipc_socket", { COMMON_SOCK_PERMS, NULL } },
{ "decnet_socket", { "bluetooth_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "iucv_socket", { COMMON_SOCK_PERMS, NULL } },
{ "atmsvc_socket", { "rxrpc_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "isdn_socket", { COMMON_SOCK_PERMS, NULL } },
{ "rds_socket", { "phonet_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "ieee802154_socket", { COMMON_SOCK_PERMS, NULL } },
{ "irda_socket", { "caif_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "alg_socket", { COMMON_SOCK_PERMS, NULL } },
{ "pppox_socket", { "nfc_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "vsock_socket", { COMMON_SOCK_PERMS, NULL } },
{ "llc_socket", { "kcm_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "qipcrtr_socket", { COMMON_SOCK_PERMS, NULL } },
{ "can_socket", { "smc_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "infiniband_pkey", { "access", NULL } },
{ "tipc_socket", { "infiniband_endport", { "manage_subnet", NULL } },
{ COMMON_SOCK_PERMS, NULL } },
{ "bluetooth_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "iucv_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "rxrpc_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "isdn_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "phonet_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "ieee802154_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "caif_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "alg_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "nfc_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "vsock_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "kcm_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "qipcrtr_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "smc_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "infiniband_pkey",
{ "access", NULL } },
{ "infiniband_endport",
{ "manage_subnet", NULL } },
{ "bpf", { "bpf",
{ "map_create", "map_read", "map_write", "prog_load", "prog_run", { "map_create", "map_read", "map_write", "prog_load", "prog_run",
NULL } }, NULL } },
{ "xdp_socket", { "xdp_socket", { COMMON_SOCK_PERMS, NULL } },
{ COMMON_SOCK_PERMS, NULL } }, { "mctp_socket", { COMMON_SOCK_PERMS, NULL } },
{ "mctp_socket",
{ COMMON_SOCK_PERMS, NULL } },
{ "perf_event", { "perf_event",
{ "open", "cpu", "kernel", "tracepoint", "read", "write", NULL } }, { "open", "cpu", "kernel", "tracepoint", "read", "write", NULL } },
{ "anon_inode", { "anon_inode", { COMMON_FILE_PERMS, NULL } },
{ COMMON_FILE_PERMS, NULL } }, { "io_uring", { "override_creds", "sqpoll", "cmd", NULL } },
{ "io_uring", { "user_namespace", { "create", NULL } },
{ "override_creds", "sqpoll", "cmd", NULL } },
{ "user_namespace",
{ "create", NULL } },
{ NULL } { NULL }
}; };
#if PF_MAX > 46 #if PF_MAX > 46
#error New address family defined, please update secclass_map. #error New address family defined, please update secclass_map.
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#include "security.h" #include "security.h"
int security_get_bools(struct selinux_policy *policy, int security_get_bools(struct selinux_policy *policy, u32 *len, char ***names,
u32 *len, char ***names, int **values); int **values);
int security_set_bools(u32 len, int *values); int security_set_bools(u32 len, int *values);
......
...@@ -25,4 +25,4 @@ static inline void selinux_ima_measure_state_locked(void) ...@@ -25,4 +25,4 @@ static inline void selinux_ima_measure_state_locked(void)
} }
#endif #endif
#endif /* _SELINUX_IMA_H_ */ #endif /* _SELINUX_IMA_H_ */
...@@ -3,33 +3,32 @@ ...@@ -3,33 +3,32 @@
#include <linux/stddef.h> #include <linux/stddef.h>
static const char *const initial_sid_to_string[] = { static const char *const initial_sid_to_string[] = {
NULL, NULL, /* zero placeholder, not used */
"kernel", "kernel", /* kernel / SECINITSID_KERNEL */
"security", "security", /* security / SECINITSID_SECURITY */
"unlabeled", "unlabeled", /* unlabeled / SECINITSID_UNLABELED */
NULL, NULL, /* fs */
"file", "file", /* file / SECINITSID_FILE */
NULL, NULL, /* file_labels */
NULL, "init", /* init / SECINITSID_INIT */
"any_socket", "any_socket", /* any_socket / SECINITSID_ANY_SOCKET */
"port", "port", /* port / SECINITSID_PORT */
"netif", "netif", /* netif / SECINITSID_NETIF */
"netmsg", "netmsg", /* netmsg / SECINITSID_NETMSG */
"node", "node", /* node / SECINITSID_NODE */
NULL, NULL, /* igmp_packet */
NULL, NULL, /* icmp_socket */
NULL, NULL, /* tcp_socket */
NULL, NULL, /* sysctl_modprobe */
NULL, NULL, /* sysctl */
NULL, NULL, /* sysctl_fs */
NULL, NULL, /* sysctl_kernel */
NULL, NULL, /* sysctl_net */
NULL, NULL, /* sysctl_net_unix */
NULL, NULL, /* sysctl_vm */
NULL, NULL, /* sysctl_dev */
NULL, NULL, /* kmod */
NULL, NULL, /* policy */
NULL, NULL, /* scmp_packet */
"devnull", "devnull", /* devnull / SECINITSID_DEVNULL */
}; };
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* Copyright (C) 2007 Hewlett-Packard Development Company, L.P. * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
* Paul Moore <paul@paul-moore.com> * Paul Moore <paul@paul-moore.com>
*/ */
#ifndef _SELINUX_NETIF_H_ #ifndef _SELINUX_NETIF_H_
#define _SELINUX_NETIF_H_ #define _SELINUX_NETIF_H_
...@@ -20,5 +21,4 @@ void sel_netif_flush(void); ...@@ -20,5 +21,4 @@ void sel_netif_flush(void);
int sel_netif_sid(struct net *ns, int ifindex, u32 *sid); int sel_netif_sid(struct net *ns, int ifindex, u32 *sid);
#endif /* _SELINUX_NETIF_H_ */ #endif /* _SELINUX_NETIF_H_ */
...@@ -32,25 +32,19 @@ void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, ...@@ -32,25 +32,19 @@ void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error,
void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec); void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec);
void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec); void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec);
int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u16 family, u32 *type,
u16 family,
u32 *type,
u32 *sid); u32 *sid);
int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family, u32 sid);
u16 family,
u32 sid);
int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
struct sk_buff *skb); struct sk_buff *skb);
int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family); int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family); void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk); void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk);
int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb, struct sk_buff *skb, u16 family,
u16 family,
struct common_audit_data *ad); struct common_audit_data *ad);
int selinux_netlbl_socket_setsockopt(struct socket *sock, int selinux_netlbl_socket_setsockopt(struct socket *sock, int level,
int level,
int optname); int optname);
int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr); int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr);
int selinux_netlbl_socket_connect_locked(struct sock *sk, int selinux_netlbl_socket_connect_locked(struct sock *sk,
...@@ -62,44 +56,40 @@ static inline void selinux_netlbl_cache_invalidate(void) ...@@ -62,44 +56,40 @@ static inline void selinux_netlbl_cache_invalidate(void)
return; return;
} }
static inline void selinux_netlbl_err(struct sk_buff *skb, static inline void selinux_netlbl_err(struct sk_buff *skb, u16 family,
u16 family, int error, int gateway)
int error,
int gateway)
{ {
return; return;
} }
static inline void selinux_netlbl_sk_security_free( static inline void
struct sk_security_struct *sksec) selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
{ {
return; return;
} }
static inline void selinux_netlbl_sk_security_reset( static inline void
struct sk_security_struct *sksec) selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
{ {
return; return;
} }
static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u16 family,
u16 family, u32 *type, u32 *sid)
u32 *type,
u32 *sid)
{ {
*type = NETLBL_NLTYPE_NONE; *type = NETLBL_NLTYPE_NONE;
*sid = SECSID_NULL; *sid = SECSID_NULL;
return 0; return 0;
} }
static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family,
u16 family,
u32 sid) u32 sid)
{ {
return 0; return 0;
} }
static inline int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, static inline int
struct sk_buff *skb) selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
struct sk_buff *skb)
{ {
return 0; return 0;
} }
...@@ -117,21 +107,18 @@ static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk, ...@@ -117,21 +107,18 @@ static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk,
{ {
return; return;
} }
static inline int selinux_netlbl_socket_post_create(struct sock *sk, static inline int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
u16 family)
{ {
return 0; return 0;
} }
static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb, struct sk_buff *skb, u16 family,
u16 family,
struct common_audit_data *ad) struct common_audit_data *ad)
{ {
return 0; return 0;
} }
static inline int selinux_netlbl_socket_setsockopt(struct socket *sock, static inline int selinux_netlbl_socket_setsockopt(struct socket *sock,
int level, int level, int optname)
int optname)
{ {
return 0; return 0;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
* Copyright (C) 2016 Mellanox Technologies * Copyright (C) 2016 Mellanox Technologies
*/ */
#ifndef _SELINUX_OBJSEC_H_ #ifndef _SELINUX_OBJSEC_H_
#define _SELINUX_OBJSEC_H_ #define _SELINUX_OBJSEC_H_
...@@ -29,122 +30,122 @@ ...@@ -29,122 +30,122 @@
#include "avc.h" #include "avc.h"
struct task_security_struct { struct task_security_struct {
u32 osid; /* SID prior to last execve */ u32 osid; /* SID prior to last execve */
u32 sid; /* current SID */ u32 sid; /* current SID */
u32 exec_sid; /* exec SID */ u32 exec_sid; /* exec SID */
u32 create_sid; /* fscreate SID */ u32 create_sid; /* fscreate SID */
u32 keycreate_sid; /* keycreate SID */ u32 keycreate_sid; /* keycreate SID */
u32 sockcreate_sid; /* fscreate SID */ u32 sockcreate_sid; /* fscreate SID */
} __randomize_layout; } __randomize_layout;
enum label_initialized { enum label_initialized {
LABEL_INVALID, /* invalid or not initialized */ LABEL_INVALID, /* invalid or not initialized */
LABEL_INITIALIZED, /* initialized */ LABEL_INITIALIZED, /* initialized */
LABEL_PENDING LABEL_PENDING
}; };
struct inode_security_struct { struct inode_security_struct {
struct inode *inode; /* back pointer to inode object */ struct inode *inode; /* back pointer to inode object */
struct list_head list; /* list of inode_security_struct */ struct list_head list; /* list of inode_security_struct */
u32 task_sid; /* SID of creating task */ u32 task_sid; /* SID of creating task */
u32 sid; /* SID of this object */ u32 sid; /* SID of this object */
u16 sclass; /* security class of this object */ u16 sclass; /* security class of this object */
unsigned char initialized; /* initialization flag */ unsigned char initialized; /* initialization flag */
spinlock_t lock; spinlock_t lock;
}; };
struct file_security_struct { struct file_security_struct {
u32 sid; /* SID of open file description */ u32 sid; /* SID of open file description */
u32 fown_sid; /* SID of file owner (for SIGIO) */ u32 fown_sid; /* SID of file owner (for SIGIO) */
u32 isid; /* SID of inode at the time of file open */ u32 isid; /* SID of inode at the time of file open */
u32 pseqno; /* Policy seqno at the time of file open */ u32 pseqno; /* Policy seqno at the time of file open */
}; };
struct superblock_security_struct { struct superblock_security_struct {
u32 sid; /* SID of file system superblock */ u32 sid; /* SID of file system superblock */
u32 def_sid; /* default SID for labeling */ u32 def_sid; /* default SID for labeling */
u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
unsigned short behavior; /* labeling behavior */ unsigned short behavior; /* labeling behavior */
unsigned short flags; /* which mount options were specified */ unsigned short flags; /* which mount options were specified */
struct mutex lock; struct mutex lock;
struct list_head isec_head; struct list_head isec_head;
spinlock_t isec_lock; spinlock_t isec_lock;
}; };
struct msg_security_struct { struct msg_security_struct {
u32 sid; /* SID of message */ u32 sid; /* SID of message */
}; };
struct ipc_security_struct { struct ipc_security_struct {
u16 sclass; /* security class of this object */ u16 sclass; /* security class of this object */
u32 sid; /* SID of IPC resource */ u32 sid; /* SID of IPC resource */
}; };
struct netif_security_struct { struct netif_security_struct {
struct net *ns; /* network namespace */ struct net *ns; /* network namespace */
int ifindex; /* device index */ int ifindex; /* device index */
u32 sid; /* SID for this interface */ u32 sid; /* SID for this interface */
}; };
struct netnode_security_struct { struct netnode_security_struct {
union { union {
__be32 ipv4; /* IPv4 node address */ __be32 ipv4; /* IPv4 node address */
struct in6_addr ipv6; /* IPv6 node address */ struct in6_addr ipv6; /* IPv6 node address */
} addr; } addr;
u32 sid; /* SID for this node */ u32 sid; /* SID for this node */
u16 family; /* address family */ u16 family; /* address family */
}; };
struct netport_security_struct { struct netport_security_struct {
u32 sid; /* SID for this node */ u32 sid; /* SID for this node */
u16 port; /* port number */ u16 port; /* port number */
u8 protocol; /* transport protocol */ u8 protocol; /* transport protocol */
}; };
struct sk_security_struct { struct sk_security_struct {
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
enum { /* NetLabel state */ enum { /* NetLabel state */
NLBL_UNSET = 0, NLBL_UNSET = 0,
NLBL_REQUIRE, NLBL_REQUIRE,
NLBL_LABELED, NLBL_LABELED,
NLBL_REQSKB, NLBL_REQSKB,
NLBL_CONNLABELED, NLBL_CONNLABELED,
} nlbl_state; } nlbl_state;
struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */ struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */
#endif #endif
u32 sid; /* SID of this object */ u32 sid; /* SID of this object */
u32 peer_sid; /* SID of peer */ u32 peer_sid; /* SID of peer */
u16 sclass; /* sock security class */ u16 sclass; /* sock security class */
enum { /* SCTP association state */ enum { /* SCTP association state */
SCTP_ASSOC_UNSET = 0, SCTP_ASSOC_UNSET = 0,
SCTP_ASSOC_SET, SCTP_ASSOC_SET,
} sctp_assoc_state; } sctp_assoc_state;
}; };
struct tun_security_struct { struct tun_security_struct {
u32 sid; /* SID for the tun device sockets */ u32 sid; /* SID for the tun device sockets */
}; };
struct key_security_struct { struct key_security_struct {
u32 sid; /* SID of key */ u32 sid; /* SID of key */
}; };
struct ib_security_struct { struct ib_security_struct {
u32 sid; /* SID of the queue pair or MAD agent */ u32 sid; /* SID of the queue pair or MAD agent */
}; };
struct pkey_security_struct { struct pkey_security_struct {
u64 subnet_prefix; /* Port subnet prefix */ u64 subnet_prefix; /* Port subnet prefix */
u16 pkey; /* PKey number */ u16 pkey; /* PKey number */
u32 sid; /* SID of pkey */ u32 sid; /* SID of pkey */
}; };
struct bpf_security_struct { struct bpf_security_struct {
u32 sid; /* SID of bpf obj creator */ u32 sid; /* SID of bpf obj creator */
}; };
struct perf_event_security_struct { struct perf_event_security_struct {
u32 sid; /* SID of perf_event obj creator */ u32 sid; /* SID of perf_event obj creator */
}; };
extern struct lsm_blob_sizes selinux_blob_sizes; extern struct lsm_blob_sizes selinux_blob_sizes;
...@@ -158,22 +159,22 @@ static inline struct file_security_struct *selinux_file(const struct file *file) ...@@ -158,22 +159,22 @@ static inline struct file_security_struct *selinux_file(const struct file *file)
return file->f_security + selinux_blob_sizes.lbs_file; return file->f_security + selinux_blob_sizes.lbs_file;
} }
static inline struct inode_security_struct *selinux_inode( static inline struct inode_security_struct *
const struct inode *inode) selinux_inode(const struct inode *inode)
{ {
if (unlikely(!inode->i_security)) if (unlikely(!inode->i_security))
return NULL; return NULL;
return inode->i_security + selinux_blob_sizes.lbs_inode; return inode->i_security + selinux_blob_sizes.lbs_inode;
} }
static inline struct msg_security_struct *selinux_msg_msg( static inline struct msg_security_struct *
const struct msg_msg *msg_msg) selinux_msg_msg(const struct msg_msg *msg_msg)
{ {
return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; return msg_msg->security + selinux_blob_sizes.lbs_msg_msg;
} }
static inline struct ipc_security_struct *selinux_ipc( static inline struct ipc_security_struct *
const struct kern_ipc_perm *ipc) selinux_ipc(const struct kern_ipc_perm *ipc)
{ {
return ipc->security + selinux_blob_sizes.lbs_ipc; return ipc->security + selinux_blob_sizes.lbs_ipc;
} }
...@@ -188,8 +189,8 @@ static inline u32 current_sid(void) ...@@ -188,8 +189,8 @@ static inline u32 current_sid(void)
return tsec->sid; return tsec->sid;
} }
static inline struct superblock_security_struct *selinux_superblock( static inline struct superblock_security_struct *
const struct super_block *superblock) selinux_superblock(const struct super_block *superblock)
{ {
return superblock->s_security + selinux_blob_sizes.lbs_superblock; return superblock->s_security + selinux_blob_sizes.lbs_superblock;
} }
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef _SELINUX_POLICYCAP_H_ #ifndef _SELINUX_POLICYCAP_H_
#define _SELINUX_POLICYCAP_H_ #define _SELINUX_POLICYCAP_H_
...@@ -12,6 +13,7 @@ enum { ...@@ -12,6 +13,7 @@ enum {
POLICYDB_CAP_NNP_NOSUID_TRANSITION, POLICYDB_CAP_NNP_NOSUID_TRANSITION,
POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS, POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
POLICYDB_CAP_IOCTL_SKIP_CLOEXEC, POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
__POLICYDB_CAP_MAX __POLICYDB_CAP_MAX
}; };
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef _SELINUX_POLICYCAP_NAMES_H_ #ifndef _SELINUX_POLICYCAP_NAMES_H_
#define _SELINUX_POLICYCAP_NAMES_H_ #define _SELINUX_POLICYCAP_NAMES_H_
#include "policycap.h" #include "policycap.h"
/* clang-format off */
/* Policy capability names */ /* Policy capability names */
const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"network_peer_controls", "network_peer_controls",
...@@ -14,6 +16,8 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { ...@@ -14,6 +16,8 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"nnp_nosuid_transition", "nnp_nosuid_transition",
"genfs_seclabel_symlinks", "genfs_seclabel_symlinks",
"ioctl_skip_cloexec", "ioctl_skip_cloexec",
"userspace_initial_context",
}; };
/* clang-format on */
#endif /* _SELINUX_POLICYCAP_NAMES_H_ */ #endif /* _SELINUX_POLICYCAP_NAMES_H_ */
...@@ -21,57 +21,57 @@ ...@@ -21,57 +21,57 @@
#include "flask.h" #include "flask.h"
#include "policycap.h" #include "policycap.h"
#define SECSID_NULL 0x00000000 /* unspecified SID */ #define SECSID_NULL 0x00000000 /* unspecified SID */
#define SECSID_WILD 0xffffffff /* wildcard SID */ #define SECSID_WILD 0xffffffff /* wildcard SID */
#define SECCLASS_NULL 0x0000 /* no class */ #define SECCLASS_NULL 0x0000 /* no class */
/* Identify specific policy version changes */ /* Identify specific policy version changes */
#define POLICYDB_VERSION_BASE 15 #define POLICYDB_VERSION_BASE 15
#define POLICYDB_VERSION_BOOL 16 #define POLICYDB_VERSION_BOOL 16
#define POLICYDB_VERSION_IPV6 17 #define POLICYDB_VERSION_IPV6 17
#define POLICYDB_VERSION_NLCLASS 18 #define POLICYDB_VERSION_NLCLASS 18
#define POLICYDB_VERSION_VALIDATETRANS 19 #define POLICYDB_VERSION_VALIDATETRANS 19
#define POLICYDB_VERSION_MLS 19 #define POLICYDB_VERSION_MLS 19
#define POLICYDB_VERSION_AVTAB 20 #define POLICYDB_VERSION_AVTAB 20
#define POLICYDB_VERSION_RANGETRANS 21 #define POLICYDB_VERSION_RANGETRANS 21
#define POLICYDB_VERSION_POLCAP 22 #define POLICYDB_VERSION_POLCAP 22
#define POLICYDB_VERSION_PERMISSIVE 23 #define POLICYDB_VERSION_PERMISSIVE 23
#define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_BOUNDARY 24
#define POLICYDB_VERSION_FILENAME_TRANS 25 #define POLICYDB_VERSION_FILENAME_TRANS 25
#define POLICYDB_VERSION_ROLETRANS 26 #define POLICYDB_VERSION_ROLETRANS 26
#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
#define POLICYDB_VERSION_DEFAULT_TYPE 28 #define POLICYDB_VERSION_DEFAULT_TYPE 28
#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 #define POLICYDB_VERSION_CONSTRAINT_NAMES 29
#define POLICYDB_VERSION_XPERMS_IOCTL 30 #define POLICYDB_VERSION_XPERMS_IOCTL 30
#define POLICYDB_VERSION_INFINIBAND 31 #define POLICYDB_VERSION_INFINIBAND 31
#define POLICYDB_VERSION_GLBLUB 32 #define POLICYDB_VERSION_GLBLUB 32
#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ #define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */
/* Range of policy versions we understand*/ /* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS #define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS
/* Mask for just the mount related flags */ /* Mask for just the mount related flags */
#define SE_MNTMASK 0x0f #define SE_MNTMASK 0x0f
/* Super block security struct flags for mount options */ /* Super block security struct flags for mount options */
/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */ /* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */
#define CONTEXT_MNT 0x01 #define CONTEXT_MNT 0x01
#define FSCONTEXT_MNT 0x02 #define FSCONTEXT_MNT 0x02
#define ROOTCONTEXT_MNT 0x04 #define ROOTCONTEXT_MNT 0x04
#define DEFCONTEXT_MNT 0x08 #define DEFCONTEXT_MNT 0x08
#define SBLABEL_MNT 0x10 #define SBLABEL_MNT 0x10
/* Non-mount related flags */ /* Non-mount related flags */
#define SE_SBINITIALIZED 0x0100 #define SE_SBINITIALIZED 0x0100
#define SE_SBPROC 0x0200 #define SE_SBPROC 0x0200
#define SE_SBGENFS 0x0400 #define SE_SBGENFS 0x0400
#define SE_SBGENFS_XATTR 0x0800 #define SE_SBGENFS_XATTR 0x0800
#define SE_SBNATIVE 0x1000 #define SE_SBNATIVE 0x1000
#define CONTEXT_STR "context" #define CONTEXT_STR "context"
#define FSCONTEXT_STR "fscontext" #define FSCONTEXT_STR "fscontext"
#define ROOTCONTEXT_STR "rootcontext" #define ROOTCONTEXT_STR "rootcontext"
#define DEFCONTEXT_STR "defcontext" #define DEFCONTEXT_STR "defcontext"
#define SECLABEL_STR "seclabel" #define SECLABEL_STR "seclabel"
struct netlbl_lsm_secattr; struct netlbl_lsm_secattr;
...@@ -81,11 +81,11 @@ extern int selinux_enabled_boot; ...@@ -81,11 +81,11 @@ extern int selinux_enabled_boot;
* type_datum properties * type_datum properties
* available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
*/ */
#define TYPEDATUM_PROPERTY_PRIMARY 0x0001 #define TYPEDATUM_PROPERTY_PRIMARY 0x0001
#define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002 #define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002
/* limitation of boundary depth */ /* limitation of boundary depth */
#define POLICYDB_BOUNDS_MAXDEPTH 4 #define POLICYDB_BOUNDS_MAXDEPTH 4
struct selinux_policy; struct selinux_policy;
...@@ -189,6 +189,12 @@ static inline bool selinux_policycap_ioctl_skip_cloexec(void) ...@@ -189,6 +189,12 @@ static inline bool selinux_policycap_ioctl_skip_cloexec(void)
selinux_state.policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]); selinux_state.policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]);
} }
static inline bool selinux_policycap_userspace_initial_context(void)
{
return READ_ONCE(
selinux_state.policycap[POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT]);
}
struct selinux_policy_convert_data; struct selinux_policy_convert_data;
struct selinux_load_state { struct selinux_load_state {
...@@ -214,12 +220,12 @@ struct av_decision { ...@@ -214,12 +220,12 @@ struct av_decision {
u32 flags; u32 flags;
}; };
#define XPERMS_ALLOWED 1 #define XPERMS_ALLOWED 1
#define XPERMS_AUDITALLOW 2 #define XPERMS_AUDITALLOW 2
#define XPERMS_DONTAUDIT 4 #define XPERMS_DONTAUDIT 4
#define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x) & 0x1f)) #define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x)&0x1f))
#define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x) & 0x1f))) #define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x)&0x1f)))
struct extended_perms_data { struct extended_perms_data {
u32 p[8]; u32 p[8];
}; };
...@@ -233,23 +239,22 @@ struct extended_perms_decision { ...@@ -233,23 +239,22 @@ struct extended_perms_decision {
}; };
struct extended_perms { struct extended_perms {
u16 len; /* length associated decision chain */ u16 len; /* length associated decision chain */
struct extended_perms_data drivers; /* flag drivers that are used */ struct extended_perms_data drivers; /* flag drivers that are used */
}; };
/* definitions of av_decision.flags */ /* definitions of av_decision.flags */
#define AVD_FLAGS_PERMISSIVE 0x0001 #define AVD_FLAGS_PERMISSIVE 0x0001
void security_compute_av(u32 ssid, u32 tsid, void security_compute_av(u32 ssid, u32 tsid, u16 tclass,
u16 tclass, struct av_decision *avd, struct av_decision *avd,
struct extended_perms *xperms); struct extended_perms *xperms);
void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, u8 driver,
u8 driver,
struct extended_perms_decision *xpermd); struct extended_perms_decision *xpermd);
void security_compute_av_user(u32 ssid, u32 tsid, void security_compute_av_user(u32 ssid, u32 tsid, u16 tclass,
u16 tclass, struct av_decision *avd); struct av_decision *avd);
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid); const struct qstr *qstr, u32 *out_sid);
...@@ -288,8 +293,7 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid); ...@@ -288,8 +293,7 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
int security_netif_sid(char *name, u32 *if_sid); int security_netif_sid(char *name, u32 *if_sid);
int security_node_sid(u16 domain, void *addr, u32 addrlen, int security_node_sid(u16 domain, void *addr, u32 addrlen, u32 *out_sid);
u32 *out_sid);
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass); u16 tclass);
...@@ -301,50 +305,47 @@ int security_bounded_transition(u32 oldsid, u32 newsid); ...@@ -301,50 +305,47 @@ int security_bounded_transition(u32 oldsid, u32 newsid);
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid,
u32 xfrm_sid,
u32 *peer_sid); u32 *peer_sid);
int security_get_classes(struct selinux_policy *policy, int security_get_classes(struct selinux_policy *policy, char ***classes,
char ***classes, u32 *nclasses); u32 *nclasses);
int security_get_permissions(struct selinux_policy *policy, int security_get_permissions(struct selinux_policy *policy, const char *class,
const char *class, char ***perms, u32 *nperms); char ***perms, u32 *nperms);
int security_get_reject_unknown(void); int security_get_reject_unknown(void);
int security_get_allow_unknown(void); int security_get_allow_unknown(void);
#define SECURITY_FS_USE_XATTR 1 /* use xattr */ #define SECURITY_FS_USE_XATTR 1 /* use xattr */
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ #define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */
#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ #define SECURITY_FS_USE_GENFS 4 /* use the genfs support */
#define SECURITY_FS_USE_NONE 5 /* no labeling support */ #define SECURITY_FS_USE_NONE 5 /* no labeling support */
#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */
#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ #define SECURITY_FS_USE_NATIVE 7 /* use native label support */
#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ #define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
int security_fs_use(struct super_block *sb); int security_fs_use(struct super_block *sb);
int security_genfs_sid(const char *fstype, const char *path, u16 sclass, int security_genfs_sid(const char *fstype, const char *path, u16 sclass,
u32 *sid); u32 *sid);
int selinux_policy_genfs_sid(struct selinux_policy *policy, int selinux_policy_genfs_sid(struct selinux_policy *policy, const char *fstype,
const char *fstype, const char *path, u16 sclass, const char *path, u16 sclass, u32 *sid);
u32 *sid);
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
u32 *sid); u32 *sid);
int security_netlbl_sid_to_secattr(u32 sid, int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr);
struct netlbl_lsm_secattr *secattr);
#else #else
static inline int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, static inline int
u32 *sid) security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, u32 *sid)
{ {
return -EIDRM; return -EIDRM;
} }
static inline int security_netlbl_sid_to_secattr(u32 sid, static inline int
struct netlbl_lsm_secattr *secattr) security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
{ {
return -ENOENT; return -ENOENT;
} }
...@@ -357,13 +358,13 @@ const char *security_get_initial_sid_context(u32 sid); ...@@ -357,13 +358,13 @@ const char *security_get_initial_sid_context(u32 sid);
*/ */
extern struct page *selinux_kernel_status_page(void); extern struct page *selinux_kernel_status_page(void);
#define SELINUX_KERNEL_STATUS_VERSION 1 #define SELINUX_KERNEL_STATUS_VERSION 1
struct selinux_kernel_status { struct selinux_kernel_status {
u32 version; /* version number of the structure */ u32 version; /* version number of the structure */
u32 sequence; /* sequence number of seqlock logic */ u32 sequence; /* sequence number of seqlock logic */
u32 enforcing; /* current setting of enforcing mode */ u32 enforcing; /* current setting of enforcing mode */
u32 policyload; /* times of policy reloaded */ u32 policyload; /* times of policy reloaded */
u32 deny_unknown; /* current setting of deny_unknown */ u32 deny_unknown; /* current setting of deny_unknown */
/* /*
* The version > 0 supports above members. * The version > 0 supports above members.
*/ */
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Author : Trent Jaeger, <jaegert@us.ibm.com> * Author : Trent Jaeger, <jaegert@us.ibm.com>
* Updated : Venkat Yekkirala, <vyekkirala@TrustedCS.com> * Updated : Venkat Yekkirala, <vyekkirala@TrustedCS.com>
*/ */
#ifndef _SELINUX_XFRM_H_ #ifndef _SELINUX_XFRM_H_
#define _SELINUX_XFRM_H_ #define _SELINUX_XFRM_H_
...@@ -13,8 +14,7 @@ ...@@ -13,8 +14,7 @@
#include <net/xfrm.h> #include <net/xfrm.h>
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
struct xfrm_user_sec_ctx *uctx, struct xfrm_user_sec_ctx *uctx, gfp_t gfp);
gfp_t gfp);
int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
struct xfrm_sec_ctx **new_ctxp); struct xfrm_sec_ctx **new_ctxp);
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
......
...@@ -336,12 +336,9 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name, ...@@ -336,12 +336,9 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
unsigned long *ino); unsigned long *ino);
/* declaration for sel_make_policy_nodes */ /* declaration for sel_make_policy_nodes */
static struct dentry *sel_make_disconnected_dir(struct super_block *sb, static struct dentry *sel_make_swapover_dir(struct super_block *sb,
unsigned long *ino); unsigned long *ino);
/* declaration for sel_make_policy_nodes */
static void sel_remove_entries(struct dentry *de);
static ssize_t sel_read_mls(struct file *filp, char __user *buf, static ssize_t sel_read_mls(struct file *filp, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -508,13 +505,13 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi, ...@@ -508,13 +505,13 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
struct selinux_policy *newpolicy) struct selinux_policy *newpolicy)
{ {
int ret = 0; int ret = 0;
struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir, *old_dentry; struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir;
unsigned int tmp_bool_num, old_bool_num; unsigned int bool_num = 0;
char **tmp_bool_names, **old_bool_names; char **bool_names = NULL;
int *tmp_bool_values, *old_bool_values; int *bool_values = NULL;
unsigned long tmp_ino = fsi->last_ino; /* Don't increment last_ino in this function */ unsigned long tmp_ino = fsi->last_ino; /* Don't increment last_ino in this function */
tmp_parent = sel_make_disconnected_dir(fsi->sb, &tmp_ino); tmp_parent = sel_make_swapover_dir(fsi->sb, &tmp_ino);
if (IS_ERR(tmp_parent)) if (IS_ERR(tmp_parent))
return PTR_ERR(tmp_parent); return PTR_ERR(tmp_parent);
...@@ -532,8 +529,8 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi, ...@@ -532,8 +529,8 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
goto out; goto out;
} }
ret = sel_make_bools(newpolicy, tmp_bool_dir, &tmp_bool_num, ret = sel_make_bools(newpolicy, tmp_bool_dir, &bool_num,
&tmp_bool_names, &tmp_bool_values); &bool_names, &bool_values);
if (ret) if (ret)
goto out; goto out;
...@@ -542,38 +539,30 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi, ...@@ -542,38 +539,30 @@ static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
if (ret) if (ret)
goto out; goto out;
lock_rename(tmp_parent, fsi->sb->s_root);
/* booleans */ /* booleans */
old_dentry = fsi->bool_dir;
lock_rename(tmp_bool_dir, old_dentry);
d_exchange(tmp_bool_dir, fsi->bool_dir); d_exchange(tmp_bool_dir, fsi->bool_dir);
old_bool_num = fsi->bool_num; swap(fsi->bool_num, bool_num);
old_bool_names = fsi->bool_pending_names; swap(fsi->bool_pending_names, bool_names);
old_bool_values = fsi->bool_pending_values; swap(fsi->bool_pending_values, bool_values);
fsi->bool_num = tmp_bool_num;
fsi->bool_pending_names = tmp_bool_names;
fsi->bool_pending_values = tmp_bool_values;
sel_remove_old_bool_data(old_bool_num, old_bool_names, old_bool_values);
fsi->bool_dir = tmp_bool_dir; fsi->bool_dir = tmp_bool_dir;
unlock_rename(tmp_bool_dir, old_dentry);
/* classes */ /* classes */
old_dentry = fsi->class_dir;
lock_rename(tmp_class_dir, old_dentry);
d_exchange(tmp_class_dir, fsi->class_dir); d_exchange(tmp_class_dir, fsi->class_dir);
fsi->class_dir = tmp_class_dir; fsi->class_dir = tmp_class_dir;
unlock_rename(tmp_class_dir, old_dentry);
unlock_rename(tmp_parent, fsi->sb->s_root);
out: out:
sel_remove_old_bool_data(bool_num, bool_names, bool_values);
/* Since the other temporary dirs are children of tmp_parent /* Since the other temporary dirs are children of tmp_parent
* this will handle all the cleanup in the case of a failure before * this will handle all the cleanup in the case of a failure before
* the swapover * the swapover
*/ */
sel_remove_entries(tmp_parent); simple_recursive_removal(tmp_parent, NULL);
dput(tmp_parent); /* d_genocide() only handles the children */
return ret; return ret;
} }
...@@ -1351,54 +1340,48 @@ static const struct file_operations sel_commit_bools_ops = { ...@@ -1351,54 +1340,48 @@ static const struct file_operations sel_commit_bools_ops = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
static void sel_remove_entries(struct dentry *de)
{
d_genocide(de);
shrink_dcache_parent(de);
}
static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir, static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
unsigned int *bool_num, char ***bool_pending_names, unsigned int *bool_num, char ***bool_pending_names,
int **bool_pending_values) int **bool_pending_values)
{ {
int ret; int ret;
ssize_t len; char **names, *page;
struct dentry *dentry = NULL;
struct inode *inode = NULL;
struct inode_security_struct *isec;
char **names = NULL, *page;
u32 i, num; u32 i, num;
int *values = NULL;
u32 sid;
ret = -ENOMEM;
page = (char *)get_zeroed_page(GFP_KERNEL); page = (char *)get_zeroed_page(GFP_KERNEL);
if (!page) if (!page)
goto out; return -ENOMEM;
ret = security_get_bools(newpolicy, &num, &names, &values); ret = security_get_bools(newpolicy, &num, &names, bool_pending_values);
if (ret) if (ret)
goto out; goto out;
*bool_num = num;
*bool_pending_names = names;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
ret = -ENOMEM; struct dentry *dentry;
struct inode *inode;
struct inode_security_struct *isec;
ssize_t len;
u32 sid;
len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
if (len >= PAGE_SIZE) {
ret = -ENAMETOOLONG;
break;
}
dentry = d_alloc_name(bool_dir, names[i]); dentry = d_alloc_name(bool_dir, names[i]);
if (!dentry) if (!dentry) {
goto out; ret = -ENOMEM;
break;
}
ret = -ENOMEM;
inode = sel_make_inode(bool_dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); inode = sel_make_inode(bool_dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
if (!inode) { if (!inode) {
dput(dentry); dput(dentry);
goto out; ret = -ENOMEM;
} break;
ret = -ENAMETOOLONG;
len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
if (len >= PAGE_SIZE) {
dput(dentry);
iput(inode);
goto out;
} }
isec = selinux_inode(inode); isec = selinux_inode(inode);
...@@ -1416,23 +1399,8 @@ static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_ ...@@ -1416,23 +1399,8 @@ static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_
inode->i_ino = i|SEL_BOOL_INO_OFFSET; inode->i_ino = i|SEL_BOOL_INO_OFFSET;
d_add(dentry, inode); d_add(dentry, inode);
} }
*bool_num = num;
*bool_pending_names = names;
*bool_pending_values = values;
free_page((unsigned long)page);
return 0;
out: out:
free_page((unsigned long)page); free_page((unsigned long)page);
if (names) {
for (i = 0; i < num; i++)
kfree(names[i]);
kfree(names);
}
kfree(values);
sel_remove_entries(bool_dir);
return ret; return ret;
} }
...@@ -1961,20 +1929,40 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name, ...@@ -1961,20 +1929,40 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
return dentry; return dentry;
} }
static struct dentry *sel_make_disconnected_dir(struct super_block *sb, static int reject_all(struct mnt_idmap *idmap, struct inode *inode, int mask)
{
return -EPERM; // no access for anyone, root or no root.
}
static const struct inode_operations swapover_dir_inode_operations = {
.lookup = simple_lookup,
.permission = reject_all,
};
static struct dentry *sel_make_swapover_dir(struct super_block *sb,
unsigned long *ino) unsigned long *ino)
{ {
struct inode *inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); struct dentry *dentry = d_alloc_name(sb->s_root, ".swapover");
struct inode *inode;
if (!inode) if (!dentry)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
inode->i_op = &simple_dir_inode_operations; inode = sel_make_inode(sb, S_IFDIR);
inode->i_fop = &simple_dir_operations; if (!inode) {
dput(dentry);
return ERR_PTR(-ENOMEM);
}
inode->i_op = &swapover_dir_inode_operations;
inode->i_ino = ++(*ino); inode->i_ino = ++(*ino);
/* directory inodes start off with i_nlink == 2 (for "." entry) */ /* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode); inc_nlink(inode);
return d_obtain_alias(inode); inode_lock(sb->s_root->d_inode);
d_add(dentry, inode);
inc_nlink(sb->s_root->d_inode);
inode_unlock(sb->s_root->d_inode);
return dentry;
} }
#define NULL_FILE_NAME "null" #define NULL_FILE_NAME "null"
......
...@@ -96,12 +96,34 @@ avtab_insert_node(struct avtab *h, struct avtab_node **dst, ...@@ -96,12 +96,34 @@ avtab_insert_node(struct avtab *h, struct avtab_node **dst,
return newnode; return newnode;
} }
static int avtab_node_cmp(const struct avtab_key *key1,
const struct avtab_key *key2)
{
u16 specified = key1->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
if (key1->source_type == key2->source_type &&
key1->target_type == key2->target_type &&
key1->target_class == key2->target_class &&
(specified & key2->specified))
return 0;
if (key1->source_type < key2->source_type)
return -1;
if (key1->source_type == key2->source_type &&
key1->target_type < key2->target_type)
return -1;
if (key1->source_type == key2->source_type &&
key1->target_type == key2->target_type &&
key1->target_class < key2->target_class)
return -1;
return 1;
}
static int avtab_insert(struct avtab *h, const struct avtab_key *key, static int avtab_insert(struct avtab *h, const struct avtab_key *key,
const struct avtab_datum *datum) const struct avtab_datum *datum)
{ {
u32 hvalue; u32 hvalue;
struct avtab_node *prev, *cur, *newnode; struct avtab_node *prev, *cur, *newnode;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); int cmp;
if (!h || !h->nslot || h->nel == U32_MAX) if (!h || !h->nslot || h->nel == U32_MAX)
return -EINVAL; return -EINVAL;
...@@ -110,23 +132,11 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key, ...@@ -110,23 +132,11 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
for (prev = NULL, cur = h->htable[hvalue]; for (prev = NULL, cur = h->htable[hvalue];
cur; cur;
prev = cur, cur = cur->next) { prev = cur, cur = cur->next) {
if (key->source_type == cur->key.source_type && cmp = avtab_node_cmp(key, &cur->key);
key->target_type == cur->key.target_type && /* extended perms may not be unique */
key->target_class == cur->key.target_class && if (cmp == 0 && !(key->specified & AVTAB_XPERMS))
(specified & cur->key.specified)) {
/* extended perms may not be unique */
if (specified & AVTAB_XPERMS)
break;
return -EEXIST; return -EEXIST;
} if (cmp <= 0)
if (key->source_type < cur->key.source_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type < cur->key.target_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class < cur->key.target_class)
break; break;
} }
...@@ -148,7 +158,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h, ...@@ -148,7 +158,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
{ {
u32 hvalue; u32 hvalue;
struct avtab_node *prev, *cur; struct avtab_node *prev, *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); int cmp;
if (!h || !h->nslot || h->nel == U32_MAX) if (!h || !h->nslot || h->nel == U32_MAX)
return NULL; return NULL;
...@@ -156,19 +166,8 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h, ...@@ -156,19 +166,8 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
for (prev = NULL, cur = h->htable[hvalue]; for (prev = NULL, cur = h->htable[hvalue];
cur; cur;
prev = cur, cur = cur->next) { prev = cur, cur = cur->next) {
if (key->source_type == cur->key.source_type && cmp = avtab_node_cmp(key, &cur->key);
key->target_type == cur->key.target_type && if (cmp <= 0)
key->target_class == cur->key.target_class &&
(specified & cur->key.specified))
break;
if (key->source_type < cur->key.source_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type < cur->key.target_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class < cur->key.target_class)
break; break;
} }
return avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue], return avtab_insert_node(h, prev ? &prev->next : &h->htable[hvalue],
...@@ -183,7 +182,7 @@ struct avtab_node *avtab_search_node(struct avtab *h, ...@@ -183,7 +182,7 @@ struct avtab_node *avtab_search_node(struct avtab *h,
{ {
u32 hvalue; u32 hvalue;
struct avtab_node *cur; struct avtab_node *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); int cmp;
if (!h || !h->nslot) if (!h || !h->nslot)
return NULL; return NULL;
...@@ -191,20 +190,10 @@ struct avtab_node *avtab_search_node(struct avtab *h, ...@@ -191,20 +190,10 @@ struct avtab_node *avtab_search_node(struct avtab *h,
hvalue = avtab_hash(key, h->mask); hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur; for (cur = h->htable[hvalue]; cur;
cur = cur->next) { cur = cur->next) {
if (key->source_type == cur->key.source_type && cmp = avtab_node_cmp(key, &cur->key);
key->target_type == cur->key.target_type && if (cmp == 0)
key->target_class == cur->key.target_class &&
(specified & cur->key.specified))
return cur; return cur;
if (cmp < 0)
if (key->source_type < cur->key.source_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type < cur->key.target_type)
break;
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class < cur->key.target_class)
break; break;
} }
return NULL; return NULL;
...@@ -213,27 +202,19 @@ struct avtab_node *avtab_search_node(struct avtab *h, ...@@ -213,27 +202,19 @@ struct avtab_node *avtab_search_node(struct avtab *h,
struct avtab_node* struct avtab_node*
avtab_search_node_next(struct avtab_node *node, u16 specified) avtab_search_node_next(struct avtab_node *node, u16 specified)
{ {
struct avtab_key tmp_key;
struct avtab_node *cur; struct avtab_node *cur;
int cmp;
if (!node) if (!node)
return NULL; return NULL;
tmp_key = node->key;
specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); tmp_key.specified = specified;
for (cur = node->next; cur; cur = cur->next) { for (cur = node->next; cur; cur = cur->next) {
if (node->key.source_type == cur->key.source_type && cmp = avtab_node_cmp(&tmp_key, &cur->key);
node->key.target_type == cur->key.target_type && if (cmp == 0)
node->key.target_class == cur->key.target_class &&
(specified & cur->key.specified))
return cur; return cur;
if (cmp < 0)
if (node->key.source_type < cur->key.source_type)
break;
if (node->key.source_type == cur->key.source_type &&
node->key.target_type < cur->key.target_type)
break;
if (node->key.source_type == cur->key.source_type &&
node->key.target_type == cur->key.target_type &&
node->key.target_class < cur->key.target_class)
break; break;
} }
return NULL; return NULL;
......
...@@ -409,16 +409,9 @@ static int roles_init(struct policydb *p) ...@@ -409,16 +409,9 @@ static int roles_init(struct policydb *p)
static u32 filenametr_hash(const void *k) static u32 filenametr_hash(const void *k)
{ {
const struct filename_trans_key *ft = k; const struct filename_trans_key *ft = k;
unsigned long hash; unsigned long salt = ft->ttype ^ ft->tclass;
unsigned int byte_num;
unsigned char focus;
hash = ft->ttype ^ ft->tclass; return full_name_hash((void *)salt, ft->name, strlen(ft->name));
byte_num = 0;
while ((focus = ft->name[byte_num++]))
hash = partial_name_hash(focus, hash);
return hash;
} }
static int filenametr_cmp(const void *k1, const void *k2) static int filenametr_cmp(const void *k1, const void *k2)
...@@ -864,6 +857,8 @@ void policydb_destroy(struct policydb *p) ...@@ -864,6 +857,8 @@ void policydb_destroy(struct policydb *p)
int policydb_load_isids(struct policydb *p, struct sidtab *s) int policydb_load_isids(struct policydb *p, struct sidtab *s)
{ {
struct ocontext *head, *c; struct ocontext *head, *c;
bool isid_init_supported = ebitmap_get_bit(&p->policycaps,
POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT);
int rc; int rc;
rc = sidtab_init(s); rc = sidtab_init(s);
...@@ -887,6 +882,13 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) ...@@ -887,6 +882,13 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
if (!name) if (!name)
continue; continue;
/*
* Also ignore SECINITSID_INIT if the policy doesn't declare
* support for it
*/
if (sid == SECINITSID_INIT && !isid_init_supported)
continue;
rc = sidtab_set_initial(s, sid, &c->context[0]); rc = sidtab_set_initial(s, sid, &c->context[0]);
if (rc) { if (rc) {
pr_err("SELinux: unable to load initial SID %s.\n", pr_err("SELinux: unable to load initial SID %s.\n",
...@@ -894,6 +896,24 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) ...@@ -894,6 +896,24 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
sidtab_destroy(s); sidtab_destroy(s);
return rc; return rc;
} }
/*
* If the policy doesn't support the "userspace_initial_context"
* capability, set SECINITSID_INIT to the same context as
* SECINITSID_KERNEL. This ensures the same behavior as before
* the reintroduction of SECINITSID_INIT, where all tasks
* started before policy load would initially get the context
* corresponding to SECINITSID_KERNEL.
*/
if (sid == SECINITSID_KERNEL && !isid_init_supported) {
rc = sidtab_set_initial(s, SECINITSID_INIT, &c->context[0]);
if (rc) {
pr_err("SELinux: unable to load initial SID %s.\n",
name);
sidtab_destroy(s);
return rc;
}
}
} }
return 0; return 0;
} }
......
...@@ -1322,8 +1322,19 @@ static int security_sid_to_context_core(u32 sid, char **scontext, ...@@ -1322,8 +1322,19 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
if (!selinux_initialized()) { if (!selinux_initialized()) {
if (sid <= SECINITSID_NUM) { if (sid <= SECINITSID_NUM) {
char *scontextp; char *scontextp;
const char *s = initial_sid_to_string[sid]; const char *s;
/*
* Before the policy is loaded, translate
* SECINITSID_INIT to "kernel", because systemd and
* libselinux < 2.6 take a getcon_raw() result that is
* both non-null and not "kernel" to mean that a policy
* is already loaded.
*/
if (sid == SECINITSID_INIT)
sid = SECINITSID_KERNEL;
s = initial_sid_to_string[sid];
if (!s) if (!s)
return -EINVAL; return -EINVAL;
*scontext_len = strlen(s) + 1; *scontext_len = strlen(s) + 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment