mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
lsm: add lsmprop_to_secctx hook
Add a new hook security_lsmprop_to_secctx() and its LSM specific implementations. The LSM specific code will use the lsm_prop element allocated for that module. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> [PM: subject line tweak] Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
870b7fdc66
commit
6f2f724f0e
@ -294,6 +294,8 @@ LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
|
||||
LSM_HOOK(int, 0, ismaclabel, const char *name)
|
||||
LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata,
|
||||
u32 *seclen)
|
||||
LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop,
|
||||
char **secdata, u32 *seclen)
|
||||
LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
|
||||
LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen)
|
||||
LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
|
||||
|
@ -535,6 +535,7 @@ int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
|
||||
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
|
||||
int security_ismaclabel(const char *name);
|
||||
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
|
||||
int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata, u32 *seclen);
|
||||
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
|
||||
void security_release_secctx(char *secdata, u32 seclen);
|
||||
void security_inode_invalidate_secctx(struct inode *inode);
|
||||
@ -1488,7 +1489,14 @@ static inline int security_ismaclabel(const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
static inline int security_secid_to_secctx(u32 secid, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int security_lsmprop_to_secctx(struct lsm_prop *prop,
|
||||
char **secdata, u32 *seclen)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ extern int apparmor_display_secid_mode;
|
||||
|
||||
struct aa_label *aa_secid_to_label(u32 secid);
|
||||
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
|
||||
int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
|
||||
u32 *seclen);
|
||||
int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
|
||||
void apparmor_release_secctx(char *secdata, u32 seclen);
|
||||
|
||||
|
@ -1517,6 +1517,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
|
||||
#endif
|
||||
|
||||
LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx),
|
||||
LSM_HOOK_INIT(lsmprop_to_secctx, apparmor_lsmprop_to_secctx),
|
||||
LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid),
|
||||
LSM_HOOK_INIT(release_secctx, apparmor_release_secctx),
|
||||
|
||||
|
@ -61,10 +61,10 @@ struct aa_label *aa_secid_to_label(u32 secid)
|
||||
return xa_load(&aa_secids, secid);
|
||||
}
|
||||
|
||||
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
static int apparmor_label_to_secctx(struct aa_label *label, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
/* TODO: cache secctx and ref count so we don't have to recreate */
|
||||
struct aa_label *label = aa_secid_to_label(secid);
|
||||
int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT;
|
||||
int len;
|
||||
|
||||
@ -90,6 +90,27 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
{
|
||||
struct aa_label *label = aa_secid_to_label(secid);
|
||||
|
||||
return apparmor_label_to_secctx(label, secdata, seclen);
|
||||
}
|
||||
|
||||
int apparmor_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
struct aa_label *label;
|
||||
|
||||
/* scaffolding */
|
||||
if (!prop->apparmor.label && prop->scaffold.secid)
|
||||
label = aa_secid_to_label(prop->scaffold.secid);
|
||||
else
|
||||
label = prop->apparmor.label;
|
||||
|
||||
return apparmor_label_to_secctx(label, secdata, seclen);
|
||||
}
|
||||
|
||||
int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
|
||||
{
|
||||
struct aa_label *label;
|
||||
|
@ -4311,6 +4311,27 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
}
|
||||
EXPORT_SYMBOL(security_secid_to_secctx);
|
||||
|
||||
/**
|
||||
* security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
|
||||
* @prop: lsm specific information
|
||||
* @secdata: secctx
|
||||
* @seclen: secctx length
|
||||
*
|
||||
* Convert a @prop entry to security context. If @secdata is NULL the
|
||||
* length of the result will be returned in @seclen, but no @secdata
|
||||
* will be returned. This does mean that the length could change between
|
||||
* calls to check the length and the next call which actually allocates
|
||||
* and returns the @secdata.
|
||||
*
|
||||
* Return: Return 0 on success, error on failure.
|
||||
*/
|
||||
int security_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
return call_int_hook(lsmprop_to_secctx, prop, secdata, seclen);
|
||||
}
|
||||
EXPORT_SYMBOL(security_lsmprop_to_secctx);
|
||||
|
||||
/**
|
||||
* security_secctx_to_secid() - Convert a secctx to a secid
|
||||
* @secdata: secctx
|
||||
|
@ -6601,8 +6601,19 @@ static int selinux_ismaclabel(const char *name)
|
||||
|
||||
static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
{
|
||||
return security_sid_to_context(secid,
|
||||
secdata, seclen);
|
||||
return security_sid_to_context(secid, secdata, seclen);
|
||||
}
|
||||
|
||||
static int selinux_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
u32 secid = prop->selinux.secid;
|
||||
|
||||
/* scaffolding */
|
||||
if (!secid)
|
||||
secid = prop->scaffold.secid;
|
||||
|
||||
return selinux_secid_to_secctx(secid, secdata, seclen);
|
||||
}
|
||||
|
||||
static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
|
||||
@ -7347,6 +7358,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
|
||||
LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
|
||||
LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
|
||||
LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
|
||||
LSM_HOOK_INIT(lsmprop_to_secctx, selinux_lsmprop_to_secctx),
|
||||
LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
|
||||
LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
|
||||
LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
|
||||
|
@ -49,7 +49,8 @@ void selinux_audit_rule_free(void *rule);
|
||||
* Returns 1 if the context id matches the rule, 0 if it does not, and
|
||||
* -errno on failure.
|
||||
*/
|
||||
int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *rule);
|
||||
int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
|
||||
void *rule);
|
||||
|
||||
/**
|
||||
* selinux_audit_rule_known - check to see if rule contains selinux fields.
|
||||
|
@ -4768,7 +4768,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
|
||||
static int smack_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
|
||||
void *vrule)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
struct smack_known *skp = prop->smack.skp;
|
||||
char *rule = vrule;
|
||||
|
||||
if (unlikely(!rule)) {
|
||||
@ -4780,10 +4780,8 @@ static int smack_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
|
||||
return 0;
|
||||
|
||||
/* scaffolding */
|
||||
if (!prop->smack.skp && prop->scaffold.secid)
|
||||
if (!skp && prop->scaffold.secid)
|
||||
skp = smack_from_secid(prop->scaffold.secid);
|
||||
else
|
||||
skp = prop->smack.skp;
|
||||
|
||||
/*
|
||||
* No need to do string comparisons. If a match occurs,
|
||||
@ -4814,7 +4812,6 @@ static int smack_ismaclabel(const char *name)
|
||||
return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* smack_secid_to_secctx - return the smack label for a secid
|
||||
* @secid: incoming integer
|
||||
@ -4833,6 +4830,29 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* smack_lsmprop_to_secctx - return the smack label
|
||||
* @prop: includes incoming Smack data
|
||||
* @secdata: destination
|
||||
* @seclen: how long it is
|
||||
*
|
||||
* Exists for audit code.
|
||||
*/
|
||||
static int smack_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
|
||||
u32 *seclen)
|
||||
{
|
||||
struct smack_known *skp = prop->smack.skp;
|
||||
|
||||
/* scaffolding */
|
||||
if (!skp && prop->scaffold.secid)
|
||||
skp = smack_from_secid(prop->scaffold.secid);
|
||||
|
||||
if (secdata)
|
||||
*secdata = skp->smk_known;
|
||||
*seclen = strlen(skp->smk_known);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* smack_secctx_to_secid - return the secid for a smack label
|
||||
* @secdata: smack label
|
||||
@ -5192,6 +5212,7 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
|
||||
|
||||
LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
|
||||
LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
|
||||
LSM_HOOK_INIT(lsmprop_to_secctx, smack_lsmprop_to_secctx),
|
||||
LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
|
||||
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
|
||||
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
|
||||
|
Loading…
Reference in New Issue
Block a user