summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Jurgens <danielj@mellanox.com>2017-05-19 08:48:57 -0400
committerPaul Moore <paul@paul-moore.com>2017-05-23 12:27:50 -0400
commitcfc4d882d41780d93471066d57d4630995427b29 (patch)
tree5dc7f313dc5caec1492c812529d83b8ae3e37dc5
parent3a976fa6767f3edebbf43839b686efaf71b8dee1 (diff)
selinux: Implement Infiniband PKey "Access" access vector
Add a type and access vector for PKeys. Implement the ib_pkey_access hook to check that the caller has permission to access the PKey on the given subnet prefix. Add an interface to get the PKey SID. Walk the PKey ocontexts to find an entry for the given subnet prefix and pkey. Signed-off-by: Daniel Jurgens <danielj@mellanox.com> Reviewed-by: James Morris <james.l.morris@oracle.com> Acked-by: Doug Ledford <dledford@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--include/linux/lsm_audit.h7
-rw-r--r--security/lsm_audit.c11
-rw-r--r--security/selinux/hooks.c22
-rw-r--r--security/selinux/include/classmap.h2
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/ss/services.c40
6 files changed, 84 insertions, 0 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index e58e577117b6..0df5639a4ff4 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -45,6 +45,11 @@ struct lsm_ioctlop_audit {
45 u16 cmd; 45 u16 cmd;
46}; 46};
47 47
48struct lsm_ibpkey_audit {
49 u64 subnet_prefix;
50 u16 pkey;
51};
52
48/* Auxiliary data to use in generating the audit record. */ 53/* Auxiliary data to use in generating the audit record. */
49struct common_audit_data { 54struct common_audit_data {
50 char type; 55 char type;
@@ -60,6 +65,7 @@ struct common_audit_data {
60#define LSM_AUDIT_DATA_DENTRY 10 65#define LSM_AUDIT_DATA_DENTRY 10
61#define LSM_AUDIT_DATA_IOCTL_OP 11 66#define LSM_AUDIT_DATA_IOCTL_OP 11
62#define LSM_AUDIT_DATA_FILE 12 67#define LSM_AUDIT_DATA_FILE 12
68#define LSM_AUDIT_DATA_IBPKEY 13
63 union { 69 union {
64 struct path path; 70 struct path path;
65 struct dentry *dentry; 71 struct dentry *dentry;
@@ -77,6 +83,7 @@ struct common_audit_data {
77 char *kmod_name; 83 char *kmod_name;
78 struct lsm_ioctlop_audit *op; 84 struct lsm_ioctlop_audit *op;
79 struct file *file; 85 struct file *file;
86 struct lsm_ibpkey_audit *ibpkey;
80 } u; 87 } u;
81 /* this union contains LSM specific data */ 88 /* this union contains LSM specific data */
82 union { 89 union {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 37f04dadc8d6..c22c99fae06a 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,17 @@ static void dump_common_audit_data(struct audit_buffer *ab,
410 audit_log_format(ab, " kmod="); 410 audit_log_format(ab, " kmod=");
411 audit_log_untrustedstring(ab, a->u.kmod_name); 411 audit_log_untrustedstring(ab, a->u.kmod_name);
412 break; 412 break;
413 case LSM_AUDIT_DATA_IBPKEY: {
414 struct in6_addr sbn_pfx;
415
416 memset(&sbn_pfx.s6_addr, 0,
417 sizeof(sbn_pfx.s6_addr));
418 memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
419 sizeof(a->u.ibpkey->subnet_prefix));
420 audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
421 a->u.ibpkey->pkey, &sbn_pfx);
422 break;
423 }
413 } /* switch (a->type) */ 424 } /* switch (a->type) */
414} 425}
415 426
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 062b459b62bf..b59255f86274 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6148,6 +6148,27 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
6148#endif 6148#endif
6149 6149
6150#ifdef CONFIG_SECURITY_INFINIBAND 6150#ifdef CONFIG_SECURITY_INFINIBAND
6151static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6152{
6153 struct common_audit_data ad;
6154 int err;
6155 u32 sid = 0;
6156 struct ib_security_struct *sec = ib_sec;
6157 struct lsm_ibpkey_audit ibpkey;
6158
6159 err = security_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
6160 if (err)
6161 return err;
6162
6163 ad.type = LSM_AUDIT_DATA_IBPKEY;
6164 ibpkey.subnet_prefix = subnet_prefix;
6165 ibpkey.pkey = pkey_val;
6166 ad.u.ibpkey = &ibpkey;
6167 return avc_has_perm(sec->sid, sid,
6168 SECCLASS_INFINIBAND_PKEY,
6169 INFINIBAND_PKEY__ACCESS, &ad);
6170}
6171
6151static int selinux_ib_alloc_security(void **ib_sec) 6172static int selinux_ib_alloc_security(void **ib_sec)
6152{ 6173{
6153 struct ib_security_struct *sec; 6174 struct ib_security_struct *sec;
@@ -6352,6 +6373,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6352 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach), 6373 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6353 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), 6374 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
6354#ifdef CONFIG_SECURITY_INFINIBAND 6375#ifdef CONFIG_SECURITY_INFINIBAND
6376 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
6355 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security), 6377 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6356 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security), 6378 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6357#endif 6379#endif
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 3e49a78f1f46..0fec1c505f84 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -231,6 +231,8 @@ struct security_class_mapping secclass_map[] = {
231 { COMMON_SOCK_PERMS, NULL } }, 231 { COMMON_SOCK_PERMS, NULL } },
232 { "smc_socket", 232 { "smc_socket",
233 { COMMON_SOCK_PERMS, NULL } }, 233 { COMMON_SOCK_PERMS, NULL } },
234 { "infiniband_pkey",
235 { "access", NULL } },
234 { NULL } 236 { NULL }
235 }; 237 };
236 238
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index b48a462cf446..592c014e369c 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -181,6 +181,8 @@ int security_get_user_sids(u32 callsid, char *username,
181 181
182int security_port_sid(u8 protocol, u16 port, u32 *out_sid); 182int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
183 183
184int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
185
184int security_netif_sid(char *name, u32 *if_sid); 186int security_netif_sid(char *name, u32 *if_sid);
185 187
186int security_node_sid(u16 domain, void *addr, u32 addrlen, 188int security_node_sid(u16 domain, void *addr, u32 addrlen,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2dccba4851f8..02257d90adc9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2233,6 +2233,46 @@ out:
2233} 2233}
2234 2234
2235/** 2235/**
2236 * security_pkey_sid - Obtain the SID for a pkey.
2237 * @subnet_prefix: Subnet Prefix
2238 * @pkey_num: pkey number
2239 * @out_sid: security identifier
2240 */
2241int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
2242{
2243 struct ocontext *c;
2244 int rc = 0;
2245
2246 read_lock(&policy_rwlock);
2247
2248 c = policydb.ocontexts[OCON_IBPKEY];
2249 while (c) {
2250 if (c->u.ibpkey.low_pkey <= pkey_num &&
2251 c->u.ibpkey.high_pkey >= pkey_num &&
2252 c->u.ibpkey.subnet_prefix == subnet_prefix)
2253 break;
2254
2255 c = c->next;
2256 }
2257
2258 if (c) {
2259 if (!c->sid[0]) {
2260 rc = sidtab_context_to_sid(&sidtab,
2261 &c->context[0],
2262 &c->sid[0]);
2263 if (rc)
2264 goto out;
2265 }
2266 *out_sid = c->sid[0];
2267 } else
2268 *out_sid = SECINITSID_UNLABELED;
2269
2270out:
2271 read_unlock(&policy_rwlock);
2272 return rc;
2273}
2274
2275/**
2236 * security_netif_sid - Obtain the SID for a network interface. 2276 * security_netif_sid - Obtain the SID for a network interface.
2237 * @name: interface name 2277 * @name: interface name
2238 * @if_sid: interface SID 2278 * @if_sid: interface SID