Smack: onlycap limits on CAP_MAC_ADMIN
Subsystems (2)
Casey Schaufler
maintainerPATCH 1/1 Smack: onlycap limits on CAP_MAC_ADMIN
From: Casey Schaufler <[email protected]>
Subject: [PATCH] Smack: onlycap limits on CAP_MAC_ADMIN
Smack is integrated with the POSIX capabilities scheme, using the capabilities CAP_MAC_OVERRIDE and CAP_MAC_ADMIN to determine if a process is allowed to ignore Smack checks or change Smack related data respectively. Smack provides an additional restriction that if an onlycap value is set by writing to /smack/onlycap only tasks with that Smack label are allowed to use CAP_MAC_OVERRIDE.
This change adds CAP_MAC_ADMIN as a capability that is affected by the onlycap mechanism.
Targeted for git://git.gitorious.org/smack-next/kernel.git
--- security/smack/smack.h | 13 +++++++++++++ security/smack/smack_access.c | 9 ++------- security/smack/smack_lsm.c | 17 +++++++++-------- security/smack/smackfs.c | 21 ++++++++++----------- 4 files changed, 34 insertions(+), 26 deletions(-)
security/smack/smack.h +13 -0
@@ -283,6 +283,19 @@ static inline char *smk_of_current(void) }/* +* Is the task privileged and allowed to be privileged +* by the onlycap rule. +*/ +static inline int smack_privileged (int cap) +{ +if (!capable (cap)) +return 0 ; +if (smack_onlycap ==NULL || smack_onlycap ==smk_of_current ()) +return 1 ; +return 0 ; +} + +/* * logging functions */ #define SMACK_AUDIT_DENIED 0x1
security/smack/smack_access.c +2 -7
@@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) }/* -* Return if a specific label has been designated as the -* only one that gets privilege and current does not -* have that label. +* Allow for priviliged to override policy. */ -if (smack_onlycap !=NULL && smack_onlycap != sp) - goto out_audit; - -if (capable (CAP_MAC_OVERRIDE )) +if (rc !=0 &&smack_privileged (CAP_MAC_OVERRIDE )) rc =0 ; out_audit:
security/smack/smack_lsm.c +9 -8
@@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file)int rc =0 ;char *sp =smk_of_current (); -if (capable (CAP_MAC_OVERRIDE )) +if (smack_privileged (CAP_MAC_OVERRIDE ))return 0 ;if (sp != smack_known_floor.smk_known)
@@ -821,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ;/* * check label validity here so import wont fail on
@@ -831,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, smk_import(value, size) == NULL) rc = -EINVAL ; }else if (strcmp (name,XATTR_NAME_SMACKTRANSMUTE ) ==0 ) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ;if (size !=TRANS_TRUE_SIZE ||strncmp (value,TRANS_TRUE ,TRANS_TRUE_SIZE ) !=0 )
@@ -927,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP)) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ; } else rc =cap_inode_removexattr (dentry, name);
@@ -1722,7 +1722,8 @@ static int smack_task_wait(struct task_struct *p)* state into account in the decision as well as * the smack value. */ -if (capable (CAP_MAC_OVERRIDE ) ||has_capability (p,CAP_MAC_OVERRIDE )) +if (smack_privileged (CAP_MAC_OVERRIDE ) || +has_capability (p,CAP_MAC_OVERRIDE )) rc =0 ;/* we log only if we didn't get overriden */ out_log:
@@ -2723,7 +2724,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,if (p != current)return -EPERM ; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (value ==NULL || size ==0 || size >=SMK_LONGLABEL )
@@ -2786,7 +2787,7 @@ static int smack_unix_stream_connect(struct sock *sock,smk_ad_setfield_u_net_sk (&ad, other);#endif -if (!capable (CAP_MAC_OVERRIDE )) +if (!smack_privileged (CAP_MAC_OVERRIDE )) rc =smk_access (ssp->smk_out, osp->smk_in,MAY_WRITE , &ad);/*
@@ -2822,7 +2823,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)smk_ad_setfield_u_net_sk (&ad, other->sk);#endif -if (!capable (CAP_MAC_OVERRIDE )) +if (!smack_privileged (CAP_MAC_OVERRIDE )) rc =smk_access (ssp->smk_out, osp->smk_in,MAY_WRITE , &ad);return rc;
security/smack/smackfs.c +10 -11
@@ -595,13 +595,12 @@ static int smk_open_load(struct inode *inode, struct file *file)static ssize_t smk_write_load (struct file *file,const char __user *buf,size_t count,loff_t *ppos) { -/* * Must have privilege. * No partial writes. * Enough data must be present. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -787,7 +786,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,* No partial writes. * Enough data must be present. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (*ppos !=0 )return -EINVAL ;
@@ -1090,7 +1089,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,* "<addr/mask, as a.b.c.d/e><space><label>" * "<addr, as a.b.c.d><space><label>" */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (*ppos !=0 )return -EINVAL ;
@@ -1267,7 +1266,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )
@@ -1334,7 +1333,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )
@@ -1412,7 +1411,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )
@@ -1503,7 +1502,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,char *data;int rc = count; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; data =kzalloc (count +1 ,GFP_KERNEL );
@@ -1586,7 +1585,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,char *sp =smk_of_task (current->cred->security);int rc = count; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;/*
@@ -1664,7 +1663,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf,char temp[32 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )
@@ -1885,7 +1884,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf,/* * Must have privilege. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
Quoted 11 lines · Casey Schaufler
From: Casey Schaufler <[email protected]>
Subject: [PATCH] Smack: onlycap limits onCAP_MAC_ADMINSmack is integrated with the POSIX capabilities scheme, using the capabilities
CAP_MAC_OVERRIDEandCAP_MAC_ADMINto determine if a process is allowed to ignore Smack checks or change Smack related data respectively. Smack provides an additional restriction that if an onlycap value is set by writing to /smack/onlycap only tasks with that Smack label are allowed to useCAP_MAC_OVERRIDE.
Quoted 6 lines
This change adds
CAP_MAC_ADMINas a capability that is affected by the onlycap mechanism.Targeted for
git://git.gitorious.org/smack-next/kernel.gitSigned-off-by Casey Schaufler <[email protected]>
Applied to git://git.gitorious.org/smack-next/kernel.git
Quoted 239 lines
--- security/smack/smack.h | 13 +++++++++++++ security/smack/smack_access.c | 9 ++------- security/smack/smack_lsm.c | 17 +++++++++-------- security/smack/smackfs.c | 21 ++++++++++----------- 4 files changed, 34 insertions(+), 26 deletions(-)security/smack/smack.h +13
-0@@ -283,6 +283,19 @@ static inline char *smk_of_current(void) }/* +* Is the task privileged and allowed to be privileged +* by the onlycap rule. +*/ +static inline int smack_privileged (int cap) +{ +if (!capable (cap)) +return 0 ; +if (smack_onlycap ==NULL || smack_onlycap ==smk_of_current ()) +return 1 ; +return 0 ; +} + +/* * logging functions */ #define SMACK_AUDIT_DENIED 0x1security/smack/smack_access.c +2
-7@@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) }/* -* Return if a specific label has been designated as the -* only one that gets privilege and current does not -* have that label. +* Allow for priviliged to override policy. */ -if (smack_onlycap !=NULL && smack_onlycap != sp) - goto out_audit; - -if (capable (CAP_MAC_OVERRIDE )) +if (rc !=0 &&smack_privileged (CAP_MAC_OVERRIDE )) rc =0 ; out_audit:security/smack/smack_lsm.c +9
-8@@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file)int rc =0 ;char *sp =smk_of_current (); -if (capable (CAP_MAC_OVERRIDE )) +if (smack_privileged (CAP_MAC_OVERRIDE ))return 0 ;if (sp != smack_known_floor.smk_known)@@ -821,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ;/* * check label validity here so import wont fail on @@ -831,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, smk_import(value, size) == NULL) rc = -EINVAL ; }else if (strcmp (name,XATTR_NAME_SMACKTRANSMUTE ) ==0 ) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ;if (size !=TRANS_TRUE_SIZE ||strncmp (value,TRANS_TRUE ,TRANS_TRUE_SIZE ) !=0 )@@ -927,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || strcmp(name, XATTR_NAME_SMACKMMAP)) { -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN )) rc = -EPERM ; } else rc =cap_inode_removexattr (dentry, name);@@ -1722,7 +1722,8 @@ static int smack_task_wait(struct task_struct *p)* state into account in the decision as well as * the smack value. */ -if (capable (CAP_MAC_OVERRIDE ) ||has_capability (p,CAP_MAC_OVERRIDE )) +if (smack_privileged (CAP_MAC_OVERRIDE ) || +has_capability (p,CAP_MAC_OVERRIDE )) rc =0 ;/* we log only if we didn't get overriden */ out_log:@@ -2723,7 +2724,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,if (p != current)return -EPERM ; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (value ==NULL || size ==0 || size >=SMK_LONGLABEL )@@ -2786,7 +2787,7 @@ static int smack_unix_stream_connect(struct sock *sock,smk_ad_setfield_u_net_sk (&ad, other);#endif -if (!capable (CAP_MAC_OVERRIDE )) +if (!smack_privileged (CAP_MAC_OVERRIDE )) rc =smk_access (ssp->smk_out, osp->smk_in,MAY_WRITE , &ad);/* @@ -2822,7 +2823,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)smk_ad_setfield_u_net_sk (&ad, other->sk);#endif -if (!capable (CAP_MAC_OVERRIDE )) +if (!smack_privileged (CAP_MAC_OVERRIDE )) rc =smk_access (ssp->smk_out, osp->smk_in,MAY_WRITE , &ad);return rc;security/smack/smackfs.c +10
-12@@ -595,13 +595,12 @@ static int smk_open_load(struct inode *inode, struct file *file)static ssize_t smk_write_load (struct file *file,const char __user *buf,size_t count,loff_t *ppos) { -/* * Must have privilege. * No partial writes. * Enough data must be present. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,@@ -787,7 +786,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,* No partial writes. * Enough data must be present. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (*ppos !=0 )return -EINVAL ;@@ -1090,7 +1089,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,* "<addr/mask, as a.b.c.d/e><space><label>" * "<addr, as a.b.c.d><space><label>" */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (*ppos !=0 )return -EINVAL ;@@ -1267,7 +1266,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )@@ -1334,7 +1333,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )@@ -1412,7 +1411,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf,char temp[80 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )@@ -1503,7 +1502,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,char *data;int rc = count; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; data =kzalloc (count +1 ,GFP_KERNEL );@@ -1586,7 +1585,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,char *sp =smk_of_task (current->cred->security);int rc = count; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;/* @@ -1664,7 +1663,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf,char temp[32 ];int i; -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;if (count >=sizeof (temp) || count ==0 )@@ -1885,7 +1884,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf,/* * Must have privilege. */ -if (!capable (CAP_MAC_ADMIN )) +if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/