You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'smack-for-4.2-stacked' of https://github.com/cschaufler/smack-next into next
This commit is contained in:
@@ -206,11 +206,11 @@ netlabel
|
||||
label. The format accepted on write is:
|
||||
"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".
|
||||
onlycap
|
||||
This contains the label processes must have for CAP_MAC_ADMIN
|
||||
This contains labels processes must have for CAP_MAC_ADMIN
|
||||
and CAP_MAC_OVERRIDE to be effective. If this file is empty
|
||||
these capabilities are effective at for processes with any
|
||||
label. The value is set by writing the desired label to the
|
||||
file or cleared by writing "-" to the file.
|
||||
label. The values are set by writing the desired labels, separated
|
||||
by spaces, to the file or cleared by writing "-" to the file.
|
||||
ptrace
|
||||
This is used to define the current ptrace policy
|
||||
0 - default: this is the policy that relies on Smack access rules.
|
||||
|
||||
+9
-16
@@ -138,6 +138,11 @@ struct smk_port_label {
|
||||
struct smack_known *smk_out; /* outgoing label */
|
||||
};
|
||||
|
||||
struct smack_onlycap {
|
||||
struct list_head list;
|
||||
struct smack_known *smk_label;
|
||||
};
|
||||
|
||||
/*
|
||||
* Mount options
|
||||
*/
|
||||
@@ -249,6 +254,7 @@ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
|
||||
struct smack_known *smk_import_entry(const char *, int);
|
||||
void smk_insert_entry(struct smack_known *skp);
|
||||
struct smack_known *smk_find_entry(const char *);
|
||||
int smack_privileged(int cap);
|
||||
|
||||
/*
|
||||
* Shared data.
|
||||
@@ -257,7 +263,6 @@ extern int smack_enabled;
|
||||
extern int smack_cipso_direct;
|
||||
extern int smack_cipso_mapped;
|
||||
extern struct smack_known *smack_net_ambient;
|
||||
extern struct smack_known *smack_onlycap;
|
||||
extern struct smack_known *smack_syslog_label;
|
||||
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||
extern struct smack_known *smack_unconfined;
|
||||
@@ -276,6 +281,9 @@ extern struct mutex smack_known_lock;
|
||||
extern struct list_head smack_known_list;
|
||||
extern struct list_head smk_netlbladdr_list;
|
||||
|
||||
extern struct mutex smack_onlycap_lock;
|
||||
extern struct list_head smack_onlycap_list;
|
||||
|
||||
#define SMACK_HASH_SLOTS 16
|
||||
extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
|
||||
|
||||
@@ -331,21 +339,6 @@ static inline struct smack_known *smk_of_current(void)
|
||||
return smk_of_task(current_security());
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the task privileged and allowed to be privileged
|
||||
* by the onlycap rule.
|
||||
*/
|
||||
static inline int smack_privileged(int cap)
|
||||
{
|
||||
struct smack_known *skp = smk_of_current();
|
||||
|
||||
if (!capable(cap))
|
||||
return 0;
|
||||
if (smack_onlycap == NULL || smack_onlycap == skp)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* logging functions
|
||||
*/
|
||||
|
||||
@@ -425,7 +425,7 @@ void smk_insert_entry(struct smack_known *skp)
|
||||
* @string: a text string that might be a Smack label
|
||||
*
|
||||
* Returns a pointer to the entry in the label list that
|
||||
* matches the passed string.
|
||||
* matches the passed string or NULL if not found.
|
||||
*/
|
||||
struct smack_known *smk_find_entry(const char *string)
|
||||
{
|
||||
@@ -448,7 +448,7 @@ struct smack_known *smk_find_entry(const char *string)
|
||||
* @string: a text string that might contain a Smack label
|
||||
* @len: the maximum size, or zero if it is NULL terminated.
|
||||
*
|
||||
* Returns a pointer to the clean label, or NULL
|
||||
* Returns a pointer to the clean label or an error code.
|
||||
*/
|
||||
char *smk_parse_smack(const char *string, int len)
|
||||
{
|
||||
@@ -464,7 +464,7 @@ char *smk_parse_smack(const char *string, int len)
|
||||
* including /smack/cipso and /smack/cipso2
|
||||
*/
|
||||
if (string[0] == '-')
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' ||
|
||||
@@ -472,11 +472,13 @@ char *smk_parse_smack(const char *string, int len)
|
||||
break;
|
||||
|
||||
if (i == 0 || i >= SMK_LONGLABEL)
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
smack = kzalloc(i + 1, GFP_KERNEL);
|
||||
if (smack != NULL)
|
||||
strncpy(smack, string, i);
|
||||
if (smack == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
strncpy(smack, string, i);
|
||||
|
||||
return smack;
|
||||
}
|
||||
@@ -523,7 +525,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
|
||||
* @len: the maximum size, or zero if it is NULL terminated.
|
||||
*
|
||||
* Returns a pointer to the entry in the label list that
|
||||
* matches the passed string, adding it if necessary.
|
||||
* matches the passed string, adding it if necessary,
|
||||
* or an error code.
|
||||
*/
|
||||
struct smack_known *smk_import_entry(const char *string, int len)
|
||||
{
|
||||
@@ -533,8 +536,8 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||
int rc;
|
||||
|
||||
smack = smk_parse_smack(string, len);
|
||||
if (smack == NULL)
|
||||
return NULL;
|
||||
if (IS_ERR(smack))
|
||||
return ERR_CAST(smack);
|
||||
|
||||
mutex_lock(&smack_known_lock);
|
||||
|
||||
@@ -543,8 +546,10 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||
goto freeout;
|
||||
|
||||
skp = kzalloc(sizeof(*skp), GFP_KERNEL);
|
||||
if (skp == NULL)
|
||||
if (skp == NULL) {
|
||||
skp = ERR_PTR(-ENOMEM);
|
||||
goto freeout;
|
||||
}
|
||||
|
||||
skp->smk_known = smack;
|
||||
skp->smk_secid = smack_next_secid++;
|
||||
@@ -577,7 +582,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||
* smk_netlbl_mls failed.
|
||||
*/
|
||||
kfree(skp);
|
||||
skp = NULL;
|
||||
skp = ERR_PTR(rc);
|
||||
freeout:
|
||||
kfree(smack);
|
||||
unlockout:
|
||||
@@ -612,3 +617,44 @@ struct smack_known *smack_from_secid(const u32 secid)
|
||||
rcu_read_unlock();
|
||||
return &smack_known_invalid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unless a process is running with one of these labels
|
||||
* even having CAP_MAC_OVERRIDE isn't enough to grant
|
||||
* privilege to violate MAC policy. If no labels are
|
||||
* designated (the empty list case) capabilities apply to
|
||||
* everyone.
|
||||
*/
|
||||
LIST_HEAD(smack_onlycap_list);
|
||||
DEFINE_MUTEX(smack_onlycap_lock);
|
||||
|
||||
/*
|
||||
* Is the task privileged and allowed to be privileged
|
||||
* by the onlycap rule.
|
||||
*
|
||||
* Returns 1 if the task is allowed to be privileged, 0 if it's not.
|
||||
*/
|
||||
int smack_privileged(int cap)
|
||||
{
|
||||
struct smack_known *skp = smk_of_current();
|
||||
struct smack_onlycap *sop;
|
||||
|
||||
if (!capable(cap))
|
||||
return 0;
|
||||
|
||||
rcu_read_lock();
|
||||
if (list_empty(&smack_onlycap_list)) {
|
||||
rcu_read_unlock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(sop, &smack_onlycap_list, list) {
|
||||
if (sop->smk_label == skp) {
|
||||
rcu_read_unlock();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+57
-39
@@ -245,8 +245,8 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
|
||||
* @ip: a pointer to the inode
|
||||
* @dp: a pointer to the dentry
|
||||
*
|
||||
* Returns a pointer to the master list entry for the Smack label
|
||||
* or NULL if there was no label to fetch.
|
||||
* Returns a pointer to the master list entry for the Smack label,
|
||||
* NULL if there was no label to fetch, or an error code.
|
||||
*/
|
||||
static struct smack_known *smk_fetch(const char *name, struct inode *ip,
|
||||
struct dentry *dp)
|
||||
@@ -256,14 +256,18 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
|
||||
struct smack_known *skp = NULL;
|
||||
|
||||
if (ip->i_op->getxattr == NULL)
|
||||
return NULL;
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
|
||||
if (rc > 0)
|
||||
if (rc < 0)
|
||||
skp = ERR_PTR(rc);
|
||||
else if (rc == 0)
|
||||
skp = NULL;
|
||||
else
|
||||
skp = smk_import_entry(buffer, rc);
|
||||
|
||||
kfree(buffer);
|
||||
@@ -605,40 +609,44 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
|
||||
if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
|
||||
op += strlen(SMK_FSHAT);
|
||||
skp = smk_import_entry(op, 0);
|
||||
if (skp != NULL) {
|
||||
sp->smk_hat = skp;
|
||||
specified = 1;
|
||||
}
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
sp->smk_hat = skp;
|
||||
specified = 1;
|
||||
|
||||
} else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
|
||||
op += strlen(SMK_FSFLOOR);
|
||||
skp = smk_import_entry(op, 0);
|
||||
if (skp != NULL) {
|
||||
sp->smk_floor = skp;
|
||||
specified = 1;
|
||||
}
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
sp->smk_floor = skp;
|
||||
specified = 1;
|
||||
|
||||
} else if (strncmp(op, SMK_FSDEFAULT,
|
||||
strlen(SMK_FSDEFAULT)) == 0) {
|
||||
op += strlen(SMK_FSDEFAULT);
|
||||
skp = smk_import_entry(op, 0);
|
||||
if (skp != NULL) {
|
||||
sp->smk_default = skp;
|
||||
specified = 1;
|
||||
}
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
sp->smk_default = skp;
|
||||
specified = 1;
|
||||
|
||||
} else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
|
||||
op += strlen(SMK_FSROOT);
|
||||
skp = smk_import_entry(op, 0);
|
||||
if (skp != NULL) {
|
||||
sp->smk_root = skp;
|
||||
specified = 1;
|
||||
}
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
sp->smk_root = skp;
|
||||
specified = 1;
|
||||
|
||||
} else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
|
||||
op += strlen(SMK_FSTRANS);
|
||||
skp = smk_import_entry(op, 0);
|
||||
if (skp != NULL) {
|
||||
sp->smk_root = skp;
|
||||
transmute = 1;
|
||||
specified = 1;
|
||||
}
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
sp->smk_root = skp;
|
||||
transmute = 1;
|
||||
specified = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1118,7 +1126,9 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
|
||||
|
||||
if (rc == 0 && check_import) {
|
||||
skp = size ? smk_import_entry(value, size) : NULL;
|
||||
if (skp == NULL || (check_star &&
|
||||
if (IS_ERR(skp))
|
||||
rc = PTR_ERR(skp);
|
||||
else if (skp == NULL || (check_star &&
|
||||
(skp == &smack_known_star || skp == &smack_known_web)))
|
||||
rc = -EINVAL;
|
||||
}
|
||||
@@ -1158,19 +1168,19 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
|
||||
|
||||
if (strcmp(name, XATTR_NAME_SMACK) == 0) {
|
||||
skp = smk_import_entry(value, size);
|
||||
if (skp != NULL)
|
||||
if (!IS_ERR(skp))
|
||||
isp->smk_inode = skp;
|
||||
else
|
||||
isp->smk_inode = &smack_known_invalid;
|
||||
} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
|
||||
skp = smk_import_entry(value, size);
|
||||
if (skp != NULL)
|
||||
if (!IS_ERR(skp))
|
||||
isp->smk_task = skp;
|
||||
else
|
||||
isp->smk_task = &smack_known_invalid;
|
||||
} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
|
||||
skp = smk_import_entry(value, size);
|
||||
if (skp != NULL)
|
||||
if (!IS_ERR(skp))
|
||||
isp->smk_mmap = skp;
|
||||
else
|
||||
isp->smk_mmap = &smack_known_invalid;
|
||||
@@ -1658,6 +1668,9 @@ static int smack_file_receive(struct file *file)
|
||||
struct smk_audit_info ad;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
if (unlikely(IS_PRIVATE(inode)))
|
||||
return 0;
|
||||
|
||||
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
|
||||
smk_ad_setfield_u_fs_path(&ad, file->f_path);
|
||||
/*
|
||||
@@ -2400,8 +2413,8 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
|
||||
return -EINVAL;
|
||||
|
||||
skp = smk_import_entry(value, size);
|
||||
if (skp == NULL)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
|
||||
if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
|
||||
nsp->smk_inode = skp;
|
||||
@@ -3174,7 +3187,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
|
||||
*/
|
||||
dp = dget(opt_dentry);
|
||||
skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
|
||||
if (skp != NULL)
|
||||
if (!IS_ERR_OR_NULL(skp))
|
||||
final = skp;
|
||||
|
||||
/*
|
||||
@@ -3211,11 +3224,14 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
|
||||
* Don't let the exec or mmap label be "*" or "@".
|
||||
*/
|
||||
skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
|
||||
if (skp == &smack_known_star || skp == &smack_known_web)
|
||||
if (IS_ERR(skp) || skp == &smack_known_star ||
|
||||
skp == &smack_known_web)
|
||||
skp = NULL;
|
||||
isp->smk_task = skp;
|
||||
|
||||
skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
|
||||
if (skp == &smack_known_star || skp == &smack_known_web)
|
||||
if (IS_ERR(skp) || skp == &smack_known_star ||
|
||||
skp == &smack_known_web)
|
||||
skp = NULL;
|
||||
isp->smk_mmap = skp;
|
||||
|
||||
@@ -3299,8 +3315,8 @@ static int smack_setprocattr(struct task_struct *p, char *name,
|
||||
return -EINVAL;
|
||||
|
||||
skp = smk_import_entry(value, size);
|
||||
if (skp == NULL)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
|
||||
/*
|
||||
* No process is ever allowed the web ("@") label.
|
||||
@@ -4075,8 +4091,10 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
return -EINVAL;
|
||||
|
||||
skp = smk_import_entry(rulestr, 0);
|
||||
if (skp)
|
||||
*rule = skp->smk_known;
|
||||
if (IS_ERR(skp))
|
||||
return PTR_ERR(skp);
|
||||
|
||||
*rule = skp->smk_known;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+196
-125
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user