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:
Casey Schaufler 2024-10-09 10:32:11 -07:00 committed by Paul Moore
parent 870b7fdc66
commit 6f2f724f0e
9 changed files with 100 additions and 11 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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),

View File

@ -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;

View File

@ -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

View File

@ -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),

View File

@ -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.

View File

@ -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),