aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack_lsm.c123
-rw-r--r--security/smack/smackfs.c61
2 files changed, 148 insertions, 36 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 2b5d6f72f678..770eb067e165 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -584,14 +584,20 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
584static int smack_inode_setxattr(struct dentry *dentry, char *name, 584static int smack_inode_setxattr(struct dentry *dentry, char *name,
585 void *value, size_t size, int flags) 585 void *value, size_t size, int flags)
586{ 586{
587 if (!capable(CAP_MAC_ADMIN)) { 587 int rc = 0;
588 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
589 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
590 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0)
591 return -EPERM;
592 }
593 588
594 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 589 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
590 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
591 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
592 if (!capable(CAP_MAC_ADMIN))
593 rc = -EPERM;
594 } else
595 rc = cap_inode_setxattr(dentry, name, value, size, flags);
596
597 if (rc == 0)
598 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
599
600 return rc;
595} 601}
596 602
597/** 603/**
@@ -658,10 +664,20 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name)
658 */ 664 */
659static int smack_inode_removexattr(struct dentry *dentry, char *name) 665static int smack_inode_removexattr(struct dentry *dentry, char *name)
660{ 666{
661 if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN)) 667 int rc = 0;
662 return -EPERM;
663 668
664 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 669 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
670 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
671 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
672 if (!capable(CAP_MAC_ADMIN))
673 rc = -EPERM;
674 } else
675 rc = cap_inode_removexattr(dentry, name);
676
677 if (rc == 0)
678 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
679
680 return rc;
665} 681}
666 682
667/** 683/**
@@ -1016,7 +1032,12 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1016 */ 1032 */
1017static int smack_task_setnice(struct task_struct *p, int nice) 1033static int smack_task_setnice(struct task_struct *p, int nice)
1018{ 1034{
1019 return smk_curacc(p->security, MAY_WRITE); 1035 int rc;
1036
1037 rc = cap_task_setnice(p, nice);
1038 if (rc == 0)
1039 rc = smk_curacc(p->security, MAY_WRITE);
1040 return rc;
1020} 1041}
1021 1042
1022/** 1043/**
@@ -1028,7 +1049,12 @@ static int smack_task_setnice(struct task_struct *p, int nice)
1028 */ 1049 */
1029static int smack_task_setioprio(struct task_struct *p, int ioprio) 1050static int smack_task_setioprio(struct task_struct *p, int ioprio)
1030{ 1051{
1031 return smk_curacc(p->security, MAY_WRITE); 1052 int rc;
1053
1054 rc = cap_task_setioprio(p, ioprio);
1055 if (rc == 0)
1056 rc = smk_curacc(p->security, MAY_WRITE);
1057 return rc;
1032} 1058}
1033 1059
1034/** 1060/**
@@ -1053,7 +1079,12 @@ static int smack_task_getioprio(struct task_struct *p)
1053static int smack_task_setscheduler(struct task_struct *p, int policy, 1079static int smack_task_setscheduler(struct task_struct *p, int policy,
1054 struct sched_param *lp) 1080 struct sched_param *lp)
1055{ 1081{
1056 return smk_curacc(p->security, MAY_WRITE); 1082 int rc;
1083
1084 rc = cap_task_setscheduler(p, policy, lp);
1085 if (rc == 0)
1086 rc = smk_curacc(p->security, MAY_WRITE);
1087 return rc;
1057} 1088}
1058 1089
1059/** 1090/**
@@ -1093,6 +1124,11 @@ static int smack_task_movememory(struct task_struct *p)
1093static int smack_task_kill(struct task_struct *p, struct siginfo *info, 1124static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1094 int sig, u32 secid) 1125 int sig, u32 secid)
1095{ 1126{
1127 int rc;
1128
1129 rc = cap_task_kill(p, info, sig, secid);
1130 if (rc != 0)
1131 return rc;
1096 /* 1132 /*
1097 * Special cases where signals really ought to go through 1133 * Special cases where signals really ought to go through
1098 * in spite of policy. Stephen Smalley suggests it may 1134 * in spite of policy. Stephen Smalley suggests it may
@@ -1251,9 +1287,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
1251 1287
1252 switch (smack_net_nltype) { 1288 switch (smack_net_nltype) {
1253 case NETLBL_NLTYPE_CIPSOV4: 1289 case NETLBL_NLTYPE_CIPSOV4:
1254 nlsp->domain = NULL; 1290 nlsp->domain = kstrdup(smack, GFP_ATOMIC);
1255 nlsp->flags = NETLBL_SECATTR_DOMAIN; 1291 nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
1256 nlsp->flags |= NETLBL_SECATTR_MLS_LVL;
1257 1292
1258 rc = smack_to_cipso(smack, &cipso); 1293 rc = smack_to_cipso(smack, &cipso);
1259 if (rc == 0) { 1294 if (rc == 0) {
@@ -1282,15 +1317,14 @@ static int smack_netlabel(struct sock *sk)
1282{ 1317{
1283 struct socket_smack *ssp; 1318 struct socket_smack *ssp;
1284 struct netlbl_lsm_secattr secattr; 1319 struct netlbl_lsm_secattr secattr;
1285 int rc = 0; 1320 int rc;
1286 1321
1287 ssp = sk->sk_security; 1322 ssp = sk->sk_security;
1288 netlbl_secattr_init(&secattr); 1323 netlbl_secattr_init(&secattr);
1289 smack_to_secattr(ssp->smk_out, &secattr); 1324 smack_to_secattr(ssp->smk_out, &secattr);
1290 if (secattr.flags != NETLBL_SECATTR_NONE) 1325 rc = netlbl_sock_setattr(sk, &secattr);
1291 rc = netlbl_sock_setattr(sk, &secattr);
1292
1293 netlbl_secattr_destroy(&secattr); 1326 netlbl_secattr_destroy(&secattr);
1327
1294 return rc; 1328 return rc;
1295} 1329}
1296 1330
@@ -1313,6 +1347,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1313 struct inode_smack *nsp = inode->i_security; 1347 struct inode_smack *nsp = inode->i_security;
1314 struct socket_smack *ssp; 1348 struct socket_smack *ssp;
1315 struct socket *sock; 1349 struct socket *sock;
1350 int rc = 0;
1316 1351
1317 if (value == NULL || size > SMK_LABELLEN) 1352 if (value == NULL || size > SMK_LABELLEN)
1318 return -EACCES; 1353 return -EACCES;
@@ -1341,7 +1376,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1341 ssp->smk_in = sp; 1376 ssp->smk_in = sp;
1342 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1377 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1343 ssp->smk_out = sp; 1378 ssp->smk_out = sp;
1344 return smack_netlabel(sock->sk); 1379 rc = smack_netlabel(sock->sk);
1380 if (rc != 0)
1381 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
1382 __func__, -rc);
1345 } else 1383 } else
1346 return -EOPNOTSUPP; 1384 return -EOPNOTSUPP;
1347 1385
@@ -1776,6 +1814,27 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
1776 return smk_curacc(isp, may); 1814 return smk_curacc(isp, may);
1777} 1815}
1778 1816
1817/* module stacking operations */
1818
1819/**
1820 * smack_register_security - stack capability module
1821 * @name: module name
1822 * @ops: module operations - ignored
1823 *
1824 * Allow the capability module to register.
1825 */
1826static int smack_register_security(const char *name,
1827 struct security_operations *ops)
1828{
1829 if (strcmp(name, "capability") != 0)
1830 return -EINVAL;
1831
1832 printk(KERN_INFO "%s: Registering secondary module %s\n",
1833 __func__, name);
1834
1835 return 0;
1836}
1837
1779/** 1838/**
1780 * smack_d_instantiate - Make sure the blob is correct on an inode 1839 * smack_d_instantiate - Make sure the blob is correct on an inode
1781 * @opt_dentry: unused 1840 * @opt_dentry: unused
@@ -2214,6 +2273,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
2214 ssp->smk_packet[0] = '\0'; 2273 ssp->smk_packet[0] = '\0';
2215 2274
2216 rc = smack_netlabel(sk); 2275 rc = smack_netlabel(sk);
2276 if (rc != 0)
2277 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
2278 __func__, -rc);
2217} 2279}
2218 2280
2219/** 2281/**
@@ -2346,6 +2408,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
2346} 2408}
2347 2409
2348/* 2410/*
2411 * smack_secctx_to_secid - return the secid for a smack label
2412 * @secdata: smack label
2413 * @seclen: how long result is
2414 * @secid: outgoing integer
2415 *
2416 * Exists for audit and networking code.
2417 */
2418static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
2419{
2420 *secid = smack_to_secid(secdata);
2421 return 0;
2422}
2423
2424/*
2349 * smack_release_secctx - don't do anything. 2425 * smack_release_secctx - don't do anything.
2350 * @key_ref: unused 2426 * @key_ref: unused
2351 * @context: unused 2427 * @context: unused
@@ -2393,6 +2469,8 @@ static struct security_operations smack_ops = {
2393 .inode_post_setxattr = smack_inode_post_setxattr, 2469 .inode_post_setxattr = smack_inode_post_setxattr,
2394 .inode_getxattr = smack_inode_getxattr, 2470 .inode_getxattr = smack_inode_getxattr,
2395 .inode_removexattr = smack_inode_removexattr, 2471 .inode_removexattr = smack_inode_removexattr,
2472 .inode_need_killpriv = cap_inode_need_killpriv,
2473 .inode_killpriv = cap_inode_killpriv,
2396 .inode_getsecurity = smack_inode_getsecurity, 2474 .inode_getsecurity = smack_inode_getsecurity,
2397 .inode_setsecurity = smack_inode_setsecurity, 2475 .inode_setsecurity = smack_inode_setsecurity,
2398 .inode_listsecurity = smack_inode_listsecurity, 2476 .inode_listsecurity = smack_inode_listsecurity,
@@ -2452,6 +2530,8 @@ static struct security_operations smack_ops = {
2452 .netlink_send = cap_netlink_send, 2530 .netlink_send = cap_netlink_send,
2453 .netlink_recv = cap_netlink_recv, 2531 .netlink_recv = cap_netlink_recv,
2454 2532
2533 .register_security = smack_register_security,
2534
2455 .d_instantiate = smack_d_instantiate, 2535 .d_instantiate = smack_d_instantiate,
2456 2536
2457 .getprocattr = smack_getprocattr, 2537 .getprocattr = smack_getprocattr,
@@ -2475,6 +2555,7 @@ static struct security_operations smack_ops = {
2475 .key_permission = smack_key_permission, 2555 .key_permission = smack_key_permission,
2476#endif /* CONFIG_KEYS */ 2556#endif /* CONFIG_KEYS */
2477 .secid_to_secctx = smack_secid_to_secctx, 2557 .secid_to_secctx = smack_secid_to_secctx,
2558 .secctx_to_secid = smack_secctx_to_secid,
2478 .release_secctx = smack_release_secctx, 2559 .release_secctx = smack_release_secctx,
2479}; 2560};
2480 2561
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 15aa37f65b39..358c92c1a153 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -24,6 +24,7 @@
24#include <net/cipso_ipv4.h> 24#include <net/cipso_ipv4.h>
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/audit.h>
27#include "smack.h" 28#include "smack.h"
28 29
29/* 30/*
@@ -45,6 +46,7 @@ enum smk_inos {
45 */ 46 */
46static DEFINE_MUTEX(smack_list_lock); 47static DEFINE_MUTEX(smack_list_lock);
47static DEFINE_MUTEX(smack_cipso_lock); 48static DEFINE_MUTEX(smack_cipso_lock);
49static DEFINE_MUTEX(smack_ambient_lock);
48 50
49/* 51/*
50 * This is the "ambient" label for network traffic. 52 * This is the "ambient" label for network traffic.
@@ -342,6 +344,9 @@ void smk_cipso_doi(void)
342 struct cipso_v4_doi *doip; 344 struct cipso_v4_doi *doip;
343 struct netlbl_audit audit_info; 345 struct netlbl_audit audit_info;
344 346
347 audit_info.loginuid = audit_get_loginuid(current);
348 audit_info.secid = smack_to_secid(current->security);
349
345 rc = netlbl_cfg_map_del(NULL, &audit_info); 350 rc = netlbl_cfg_map_del(NULL, &audit_info);
346 if (rc != 0) 351 if (rc != 0)
347 printk(KERN_WARNING "%s:%d remove rc = %d\n", 352 printk(KERN_WARNING "%s:%d remove rc = %d\n",
@@ -363,6 +368,30 @@ void smk_cipso_doi(void)
363 __func__, __LINE__, rc); 368 __func__, __LINE__, rc);
364} 369}
365 370
371/**
372 * smk_unlbl_ambient - initialize the unlabeled domain
373 */
374void smk_unlbl_ambient(char *oldambient)
375{
376 int rc;
377 struct netlbl_audit audit_info;
378
379 audit_info.loginuid = audit_get_loginuid(current);
380 audit_info.secid = smack_to_secid(current->security);
381
382 if (oldambient != NULL) {
383 rc = netlbl_cfg_map_del(oldambient, &audit_info);
384 if (rc != 0)
385 printk(KERN_WARNING "%s:%d remove rc = %d\n",
386 __func__, __LINE__, rc);
387 }
388
389 rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info);
390 if (rc != 0)
391 printk(KERN_WARNING "%s:%d add rc = %d\n",
392 __func__, __LINE__, rc);
393}
394
366/* 395/*
367 * Seq_file read operations for /smack/cipso 396 * Seq_file read operations for /smack/cipso
368 */ 397 */
@@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
709 size_t cn, loff_t *ppos) 738 size_t cn, loff_t *ppos)
710{ 739{
711 ssize_t rc; 740 ssize_t rc;
712 char out[SMK_LABELLEN];
713 int asize; 741 int asize;
714 742
715 if (*ppos != 0) 743 if (*ppos != 0)
@@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
717 /* 745 /*
718 * Being careful to avoid a problem in the case where 746 * Being careful to avoid a problem in the case where
719 * smack_net_ambient gets changed in midstream. 747 * smack_net_ambient gets changed in midstream.
720 * Since smack_net_ambient is always set with a value
721 * from the label list, including initially, and those
722 * never get freed, the worst case is that the pointer
723 * gets changed just after this strncpy, in which case
724 * the value passed up is incorrect. Locking around
725 * smack_net_ambient wouldn't be any better than this
726 * copy scheme as by the time the caller got to look
727 * at the ambient value it would have cleared the lock
728 * and been changed.
729 */ 748 */
730 strncpy(out, smack_net_ambient, SMK_LABELLEN); 749 mutex_lock(&smack_ambient_lock);
731 asize = strlen(out) + 1;
732 750
733 if (cn < asize) 751 asize = strlen(smack_net_ambient) + 1;
734 return -EINVAL; 752
753 if (cn >= asize)
754 rc = simple_read_from_buffer(buf, cn, ppos,
755 smack_net_ambient, asize);
756 else
757 rc = -EINVAL;
735 758
736 rc = simple_read_from_buffer(buf, cn, ppos, out, asize); 759 mutex_unlock(&smack_ambient_lock);
737 760
738 return rc; 761 return rc;
739} 762}
@@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
751 size_t count, loff_t *ppos) 774 size_t count, loff_t *ppos)
752{ 775{
753 char in[SMK_LABELLEN]; 776 char in[SMK_LABELLEN];
777 char *oldambient;
754 char *smack; 778 char *smack;
755 779
756 if (!capable(CAP_MAC_ADMIN)) 780 if (!capable(CAP_MAC_ADMIN))
@@ -766,7 +790,13 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
766 if (smack == NULL) 790 if (smack == NULL)
767 return -EINVAL; 791 return -EINVAL;
768 792
793 mutex_lock(&smack_ambient_lock);
794
795 oldambient = smack_net_ambient;
769 smack_net_ambient = smack; 796 smack_net_ambient = smack;
797 smk_unlbl_ambient(oldambient);
798
799 mutex_unlock(&smack_ambient_lock);
770 800
771 return count; 801 return count;
772} 802}
@@ -974,6 +1004,7 @@ static int __init init_smk_fs(void)
974 1004
975 sema_init(&smack_write_sem, 1); 1005 sema_init(&smack_write_sem, 1);
976 smk_cipso_doi(); 1006 smk_cipso_doi();
1007 smk_unlbl_ambient(NULL);
977 1008
978 return err; 1009 return err;
979} 1010}