diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/capability.c | 24 | ||||
| -rw-r--r-- | security/device_cgroup.c | 2 | ||||
| -rw-r--r-- | security/integrity/evm/evm_crypto.c | 4 | ||||
| -rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
| -rw-r--r-- | security/integrity/ima/ima_main.c | 12 | ||||
| -rw-r--r-- | security/integrity/ima/ima_policy.c | 3 | ||||
| -rw-r--r-- | security/security.c | 28 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 50 | ||||
| -rw-r--r-- | security/selinux/include/classmap.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 4 |
10 files changed, 103 insertions, 27 deletions
diff --git a/security/capability.c b/security/capability.c index 0fe5a026aef8..579775088967 100644 --- a/security/capability.c +++ b/security/capability.c | |||
| @@ -709,16 +709,31 @@ static void cap_req_classify_flow(const struct request_sock *req, | |||
| 709 | { | 709 | { |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | static int cap_tun_dev_alloc_security(void **security) | ||
| 713 | { | ||
| 714 | return 0; | ||
| 715 | } | ||
| 716 | |||
| 717 | static void cap_tun_dev_free_security(void *security) | ||
| 718 | { | ||
| 719 | } | ||
| 720 | |||
| 712 | static int cap_tun_dev_create(void) | 721 | static int cap_tun_dev_create(void) |
| 713 | { | 722 | { |
| 714 | return 0; | 723 | return 0; |
| 715 | } | 724 | } |
| 716 | 725 | ||
| 717 | static void cap_tun_dev_post_create(struct sock *sk) | 726 | static int cap_tun_dev_attach_queue(void *security) |
| 727 | { | ||
| 728 | return 0; | ||
| 729 | } | ||
| 730 | |||
| 731 | static int cap_tun_dev_attach(struct sock *sk, void *security) | ||
| 718 | { | 732 | { |
| 733 | return 0; | ||
| 719 | } | 734 | } |
| 720 | 735 | ||
| 721 | static int cap_tun_dev_attach(struct sock *sk) | 736 | static int cap_tun_dev_open(void *security) |
| 722 | { | 737 | { |
| 723 | return 0; | 738 | return 0; |
| 724 | } | 739 | } |
| @@ -1050,8 +1065,11 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
| 1050 | set_to_cap_if_null(ops, secmark_refcount_inc); | 1065 | set_to_cap_if_null(ops, secmark_refcount_inc); |
| 1051 | set_to_cap_if_null(ops, secmark_refcount_dec); | 1066 | set_to_cap_if_null(ops, secmark_refcount_dec); |
| 1052 | set_to_cap_if_null(ops, req_classify_flow); | 1067 | set_to_cap_if_null(ops, req_classify_flow); |
| 1068 | set_to_cap_if_null(ops, tun_dev_alloc_security); | ||
| 1069 | set_to_cap_if_null(ops, tun_dev_free_security); | ||
| 1053 | set_to_cap_if_null(ops, tun_dev_create); | 1070 | set_to_cap_if_null(ops, tun_dev_create); |
| 1054 | set_to_cap_if_null(ops, tun_dev_post_create); | 1071 | set_to_cap_if_null(ops, tun_dev_open); |
| 1072 | set_to_cap_if_null(ops, tun_dev_attach_queue); | ||
| 1055 | set_to_cap_if_null(ops, tun_dev_attach); | 1073 | set_to_cap_if_null(ops, tun_dev_attach); |
| 1056 | #endif /* CONFIG_SECURITY_NETWORK */ | 1074 | #endif /* CONFIG_SECURITY_NETWORK */ |
| 1057 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1075 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 19ecc8de9e6b..d794abcc4b3b 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
| @@ -215,7 +215,9 @@ static void devcgroup_css_free(struct cgroup *cgroup) | |||
| 215 | struct dev_cgroup *dev_cgroup; | 215 | struct dev_cgroup *dev_cgroup; |
| 216 | 216 | ||
| 217 | dev_cgroup = cgroup_to_devcgroup(cgroup); | 217 | dev_cgroup = cgroup_to_devcgroup(cgroup); |
| 218 | mutex_lock(&devcgroup_mutex); | ||
| 218 | dev_exception_clean(dev_cgroup); | 219 | dev_exception_clean(dev_cgroup); |
| 220 | mutex_unlock(&devcgroup_mutex); | ||
| 219 | kfree(dev_cgroup); | 221 | kfree(dev_cgroup); |
| 220 | } | 222 | } |
| 221 | 223 | ||
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index dfb26918699c..7dd538ef5b83 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
| @@ -205,9 +205,9 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, | |||
| 205 | rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, | 205 | rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, |
| 206 | &xattr_data, | 206 | &xattr_data, |
| 207 | sizeof(xattr_data), 0); | 207 | sizeof(xattr_data), 0); |
| 208 | } | 208 | } else if (rc == -ENODATA && inode->i_op->removexattr) { |
| 209 | else if (rc == -ENODATA) | ||
| 210 | rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); | 209 | rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM); |
| 210 | } | ||
| 211 | return rc; | 211 | return rc; |
| 212 | } | 212 | } |
| 213 | 213 | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 3b2adb794f15..079a85dc37b2 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
| @@ -139,6 +139,7 @@ void ima_delete_rules(void); | |||
| 139 | /* Appraise integrity measurements */ | 139 | /* Appraise integrity measurements */ |
| 140 | #define IMA_APPRAISE_ENFORCE 0x01 | 140 | #define IMA_APPRAISE_ENFORCE 0x01 |
| 141 | #define IMA_APPRAISE_FIX 0x02 | 141 | #define IMA_APPRAISE_FIX 0x02 |
| 142 | #define IMA_APPRAISE_MODULES 0x04 | ||
| 142 | 143 | ||
| 143 | #ifdef CONFIG_IMA_APPRAISE | 144 | #ifdef CONFIG_IMA_APPRAISE |
| 144 | int ima_appraise_measurement(struct integrity_iint_cache *iint, | 145 | int ima_appraise_measurement(struct integrity_iint_cache *iint, |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 45de18e9a6f2..dba965de90d3 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
| @@ -291,11 +291,15 @@ EXPORT_SYMBOL_GPL(ima_file_check); | |||
| 291 | */ | 291 | */ |
| 292 | int ima_module_check(struct file *file) | 292 | int ima_module_check(struct file *file) |
| 293 | { | 293 | { |
| 294 | int rc; | 294 | int rc = 0; |
| 295 | 295 | ||
| 296 | if (!file) | 296 | if (!file) { |
| 297 | rc = INTEGRITY_UNKNOWN; | 297 | if (ima_appraise & IMA_APPRAISE_MODULES) { |
| 298 | else | 298 | #ifndef CONFIG_MODULE_SIG_FORCE |
| 299 | rc = -EACCES; /* INTEGRITY_UNKNOWN */ | ||
| 300 | #endif | ||
| 301 | } | ||
| 302 | } else | ||
| 299 | rc = process_measurement(file, file->f_dentry->d_name.name, | 303 | rc = process_measurement(file, file->f_dentry->d_name.name, |
| 300 | MAY_EXEC, MODULE_CHECK); | 304 | MAY_EXEC, MODULE_CHECK); |
| 301 | return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; | 305 | return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index af7d182d5a46..479fca940bb5 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
| @@ -523,7 +523,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
| 523 | } | 523 | } |
| 524 | if (!result && (entry->action == UNKNOWN)) | 524 | if (!result && (entry->action == UNKNOWN)) |
| 525 | result = -EINVAL; | 525 | result = -EINVAL; |
| 526 | 526 | else if (entry->func == MODULE_CHECK) | |
| 527 | ima_appraise |= IMA_APPRAISE_MODULES; | ||
| 527 | audit_log_format(ab, "res=%d", !result); | 528 | audit_log_format(ab, "res=%d", !result); |
| 528 | audit_log_end(ab); | 529 | audit_log_end(ab); |
| 529 | return result; | 530 | return result; |
diff --git a/security/security.c b/security/security.c index daa97f4ac9d1..7b88c6aeaed4 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -1254,24 +1254,42 @@ void security_secmark_refcount_dec(void) | |||
| 1254 | } | 1254 | } |
| 1255 | EXPORT_SYMBOL(security_secmark_refcount_dec); | 1255 | EXPORT_SYMBOL(security_secmark_refcount_dec); |
| 1256 | 1256 | ||
| 1257 | int security_tun_dev_alloc_security(void **security) | ||
| 1258 | { | ||
| 1259 | return security_ops->tun_dev_alloc_security(security); | ||
| 1260 | } | ||
| 1261 | EXPORT_SYMBOL(security_tun_dev_alloc_security); | ||
| 1262 | |||
| 1263 | void security_tun_dev_free_security(void *security) | ||
| 1264 | { | ||
| 1265 | security_ops->tun_dev_free_security(security); | ||
| 1266 | } | ||
| 1267 | EXPORT_SYMBOL(security_tun_dev_free_security); | ||
| 1268 | |||
| 1257 | int security_tun_dev_create(void) | 1269 | int security_tun_dev_create(void) |
| 1258 | { | 1270 | { |
| 1259 | return security_ops->tun_dev_create(); | 1271 | return security_ops->tun_dev_create(); |
| 1260 | } | 1272 | } |
| 1261 | EXPORT_SYMBOL(security_tun_dev_create); | 1273 | EXPORT_SYMBOL(security_tun_dev_create); |
| 1262 | 1274 | ||
| 1263 | void security_tun_dev_post_create(struct sock *sk) | 1275 | int security_tun_dev_attach_queue(void *security) |
| 1264 | { | 1276 | { |
| 1265 | return security_ops->tun_dev_post_create(sk); | 1277 | return security_ops->tun_dev_attach_queue(security); |
| 1266 | } | 1278 | } |
| 1267 | EXPORT_SYMBOL(security_tun_dev_post_create); | 1279 | EXPORT_SYMBOL(security_tun_dev_attach_queue); |
| 1268 | 1280 | ||
| 1269 | int security_tun_dev_attach(struct sock *sk) | 1281 | int security_tun_dev_attach(struct sock *sk, void *security) |
| 1270 | { | 1282 | { |
| 1271 | return security_ops->tun_dev_attach(sk); | 1283 | return security_ops->tun_dev_attach(sk, security); |
| 1272 | } | 1284 | } |
| 1273 | EXPORT_SYMBOL(security_tun_dev_attach); | 1285 | EXPORT_SYMBOL(security_tun_dev_attach); |
| 1274 | 1286 | ||
| 1287 | int security_tun_dev_open(void *security) | ||
| 1288 | { | ||
| 1289 | return security_ops->tun_dev_open(security); | ||
| 1290 | } | ||
| 1291 | EXPORT_SYMBOL(security_tun_dev_open); | ||
| 1292 | |||
| 1275 | #endif /* CONFIG_SECURITY_NETWORK */ | 1293 | #endif /* CONFIG_SECURITY_NETWORK */ |
| 1276 | 1294 | ||
| 1277 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1295 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 61a53367d029..ef26e9611ffb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req, | |||
| 4399 | fl->flowi_secid = req->secid; | 4399 | fl->flowi_secid = req->secid; |
| 4400 | } | 4400 | } |
| 4401 | 4401 | ||
| 4402 | static int selinux_tun_dev_alloc_security(void **security) | ||
| 4403 | { | ||
| 4404 | struct tun_security_struct *tunsec; | ||
| 4405 | |||
| 4406 | tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL); | ||
| 4407 | if (!tunsec) | ||
| 4408 | return -ENOMEM; | ||
| 4409 | tunsec->sid = current_sid(); | ||
| 4410 | |||
| 4411 | *security = tunsec; | ||
| 4412 | return 0; | ||
| 4413 | } | ||
| 4414 | |||
| 4415 | static void selinux_tun_dev_free_security(void *security) | ||
| 4416 | { | ||
| 4417 | kfree(security); | ||
| 4418 | } | ||
| 4419 | |||
| 4402 | static int selinux_tun_dev_create(void) | 4420 | static int selinux_tun_dev_create(void) |
| 4403 | { | 4421 | { |
| 4404 | u32 sid = current_sid(); | 4422 | u32 sid = current_sid(); |
| @@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void) | |||
| 4414 | NULL); | 4432 | NULL); |
| 4415 | } | 4433 | } |
| 4416 | 4434 | ||
| 4417 | static void selinux_tun_dev_post_create(struct sock *sk) | 4435 | static int selinux_tun_dev_attach_queue(void *security) |
| 4418 | { | 4436 | { |
| 4437 | struct tun_security_struct *tunsec = security; | ||
| 4438 | |||
| 4439 | return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET, | ||
| 4440 | TUN_SOCKET__ATTACH_QUEUE, NULL); | ||
| 4441 | } | ||
| 4442 | |||
| 4443 | static int selinux_tun_dev_attach(struct sock *sk, void *security) | ||
| 4444 | { | ||
| 4445 | struct tun_security_struct *tunsec = security; | ||
| 4419 | struct sk_security_struct *sksec = sk->sk_security; | 4446 | struct sk_security_struct *sksec = sk->sk_security; |
| 4420 | 4447 | ||
| 4421 | /* we don't currently perform any NetLabel based labeling here and it | 4448 | /* we don't currently perform any NetLabel based labeling here and it |
| @@ -4425,20 +4452,19 @@ static void selinux_tun_dev_post_create(struct sock *sk) | |||
| 4425 | * cause confusion to the TUN user that had no idea network labeling | 4452 | * cause confusion to the TUN user that had no idea network labeling |
| 4426 | * protocols were being used */ | 4453 | * protocols were being used */ |
| 4427 | 4454 | ||
| 4428 | /* see the comments in selinux_tun_dev_create() about why we don't use | 4455 | sksec->sid = tunsec->sid; |
| 4429 | * the sockcreate SID here */ | ||
| 4430 | |||
| 4431 | sksec->sid = current_sid(); | ||
| 4432 | sksec->sclass = SECCLASS_TUN_SOCKET; | 4456 | sksec->sclass = SECCLASS_TUN_SOCKET; |
| 4457 | |||
| 4458 | return 0; | ||
| 4433 | } | 4459 | } |
| 4434 | 4460 | ||
| 4435 | static int selinux_tun_dev_attach(struct sock *sk) | 4461 | static int selinux_tun_dev_open(void *security) |
| 4436 | { | 4462 | { |
| 4437 | struct sk_security_struct *sksec = sk->sk_security; | 4463 | struct tun_security_struct *tunsec = security; |
| 4438 | u32 sid = current_sid(); | 4464 | u32 sid = current_sid(); |
| 4439 | int err; | 4465 | int err; |
| 4440 | 4466 | ||
| 4441 | err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, | 4467 | err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET, |
| 4442 | TUN_SOCKET__RELABELFROM, NULL); | 4468 | TUN_SOCKET__RELABELFROM, NULL); |
| 4443 | if (err) | 4469 | if (err) |
| 4444 | return err; | 4470 | return err; |
| @@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk) | |||
| 4446 | TUN_SOCKET__RELABELTO, NULL); | 4472 | TUN_SOCKET__RELABELTO, NULL); |
| 4447 | if (err) | 4473 | if (err) |
| 4448 | return err; | 4474 | return err; |
| 4449 | 4475 | tunsec->sid = sid; | |
| 4450 | sksec->sid = sid; | ||
| 4451 | 4476 | ||
| 4452 | return 0; | 4477 | return 0; |
| 4453 | } | 4478 | } |
| @@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = { | |||
| 5642 | .secmark_refcount_inc = selinux_secmark_refcount_inc, | 5667 | .secmark_refcount_inc = selinux_secmark_refcount_inc, |
| 5643 | .secmark_refcount_dec = selinux_secmark_refcount_dec, | 5668 | .secmark_refcount_dec = selinux_secmark_refcount_dec, |
| 5644 | .req_classify_flow = selinux_req_classify_flow, | 5669 | .req_classify_flow = selinux_req_classify_flow, |
| 5670 | .tun_dev_alloc_security = selinux_tun_dev_alloc_security, | ||
| 5671 | .tun_dev_free_security = selinux_tun_dev_free_security, | ||
| 5645 | .tun_dev_create = selinux_tun_dev_create, | 5672 | .tun_dev_create = selinux_tun_dev_create, |
| 5646 | .tun_dev_post_create = selinux_tun_dev_post_create, | 5673 | .tun_dev_attach_queue = selinux_tun_dev_attach_queue, |
| 5647 | .tun_dev_attach = selinux_tun_dev_attach, | 5674 | .tun_dev_attach = selinux_tun_dev_attach, |
| 5675 | .tun_dev_open = selinux_tun_dev_open, | ||
| 5648 | 5676 | ||
| 5649 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 5677 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 5650 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 5678 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index df2de54a958d..14d04e63b1f0 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
| @@ -150,6 +150,6 @@ struct security_class_mapping secclass_map[] = { | |||
| 150 | NULL } }, | 150 | NULL } }, |
| 151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
| 152 | { "tun_socket", | 152 | { "tun_socket", |
| 153 | { COMMON_SOCK_PERMS, NULL } }, | 153 | { COMMON_SOCK_PERMS, "attach_queue", NULL } }, |
| 154 | { NULL } | 154 | { NULL } |
| 155 | }; | 155 | }; |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 26c7eee1c309..aa47bcabb5f6 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
| @@ -110,6 +110,10 @@ struct sk_security_struct { | |||
| 110 | u16 sclass; /* sock security class */ | 110 | u16 sclass; /* sock security class */ |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | struct tun_security_struct { | ||
| 114 | u32 sid; /* SID for the tun device sockets */ | ||
| 115 | }; | ||
| 116 | |||
| 113 | struct key_security_struct { | 117 | struct key_security_struct { |
| 114 | u32 sid; /* SID of key */ | 118 | u32 sid; /* SID of key */ |
| 115 | }; | 119 | }; |
