0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/errno.h>
0014 #include <linux/err.h>
0015 #include <linux/gfp.h>
0016 #include <linux/slab.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/xarray.h>
0019
0020 #include "include/cred.h"
0021 #include "include/lib.h"
0022 #include "include/secid.h"
0023 #include "include/label.h"
0024 #include "include/policy_ns.h"
0025
0026
0027
0028
0029
0030 #define AA_FIRST_SECID 2
0031
0032 static DEFINE_XARRAY_FLAGS(aa_secids, XA_FLAGS_LOCK_IRQ | XA_FLAGS_TRACK_FREE);
0033
0034 int apparmor_display_secid_mode;
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 void aa_secid_update(u32 secid, struct aa_label *label)
0048 {
0049 unsigned long flags;
0050
0051 xa_lock_irqsave(&aa_secids, flags);
0052 __xa_store(&aa_secids, secid, label, 0);
0053 xa_unlock_irqrestore(&aa_secids, flags);
0054 }
0055
0056
0057
0058
0059
0060 struct aa_label *aa_secid_to_label(u32 secid)
0061 {
0062 return xa_load(&aa_secids, secid);
0063 }
0064
0065 int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
0066 {
0067
0068 struct aa_label *label = aa_secid_to_label(secid);
0069 int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED | FLAG_ABS_ROOT;
0070 int len;
0071
0072 AA_BUG(!seclen);
0073
0074 if (!label)
0075 return -EINVAL;
0076
0077 if (apparmor_display_secid_mode)
0078 flags |= FLAG_SHOW_MODE;
0079
0080 if (secdata)
0081 len = aa_label_asxprint(secdata, root_ns, label,
0082 flags, GFP_ATOMIC);
0083 else
0084 len = aa_label_snxprint(NULL, 0, root_ns, label, flags);
0085
0086 if (len < 0)
0087 return -ENOMEM;
0088
0089 *seclen = len;
0090
0091 return 0;
0092 }
0093
0094 int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
0095 {
0096 struct aa_label *label;
0097
0098 label = aa_label_strn_parse(&root_ns->unconfined->label, secdata,
0099 seclen, GFP_KERNEL, false, false);
0100 if (IS_ERR(label))
0101 return PTR_ERR(label);
0102 *secid = label->secid;
0103
0104 return 0;
0105 }
0106
0107 void apparmor_release_secctx(char *secdata, u32 seclen)
0108 {
0109 kfree(secdata);
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 int aa_alloc_secid(struct aa_label *label, gfp_t gfp)
0121 {
0122 unsigned long flags;
0123 int ret;
0124
0125 xa_lock_irqsave(&aa_secids, flags);
0126 ret = __xa_alloc(&aa_secids, &label->secid, label,
0127 XA_LIMIT(AA_FIRST_SECID, INT_MAX), gfp);
0128 xa_unlock_irqrestore(&aa_secids, flags);
0129
0130 if (ret < 0) {
0131 label->secid = AA_SECID_INVALID;
0132 return ret;
0133 }
0134
0135 return 0;
0136 }
0137
0138
0139
0140
0141
0142 void aa_free_secid(u32 secid)
0143 {
0144 unsigned long flags;
0145
0146 xa_lock_irqsave(&aa_secids, flags);
0147 __xa_erase(&aa_secids, secid);
0148 xa_unlock_irqrestore(&aa_secids, flags);
0149 }