Skip to content

Commit 4aa1761

Browse files
cgzonespcmoore
authored andcommitted
selinux: add support for xperms in conditional policies
Add support for extended permission rules in conditional policies. Currently the kernel accepts such rules already, but evaluating a security decision will hit a BUG() in services_compute_xperms_decision(). Thus reject extended permission rules in conditional policies for current policy versions. Add a new policy version for this feature. Signed-off-by: Christian Göttsche <[email protected]> Acked-by: Stephen Smalley <[email protected]> Tested-by: Stephen Smalley <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 034294f commit 4aa1761

File tree

6 files changed

+26
-9
lines changed

6 files changed

+26
-9
lines changed

security/selinux/include/security.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@
4646
#define POLICYDB_VERSION_INFINIBAND 31
4747
#define POLICYDB_VERSION_GLBLUB 32
4848
#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */
49+
#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */
4950

5051
/* Range of policy versions we understand*/
5152
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
52-
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS
53+
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS
5354

5455
/* Mask for just the mount related flags */
5556
#define SE_MNTMASK 0x0f

security/selinux/ss/avtab.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static const uint16_t spec_order[] = {
339339
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
340340
int (*insertf)(struct avtab *a, const struct avtab_key *k,
341341
const struct avtab_datum *d, void *p),
342-
void *p)
342+
void *p, bool conditional)
343343
{
344344
__le16 buf16[4];
345345
u16 enabled;
@@ -457,6 +457,13 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
457457
"was specified\n",
458458
vers);
459459
return -EINVAL;
460+
} else if ((vers < POLICYDB_VERSION_COND_XPERMS) &&
461+
(key.specified & AVTAB_XPERMS) && conditional) {
462+
pr_err("SELinux: avtab: policy version %u does not "
463+
"support extended permissions rules in conditional "
464+
"policies and one was specified\n",
465+
vers);
466+
return -EINVAL;
460467
} else if (key.specified & AVTAB_XPERMS) {
461468
memset(&xperms, 0, sizeof(struct avtab_extended_perms));
462469
rc = next_entry(&xperms.specified, fp, sizeof(u8));
@@ -523,7 +530,7 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
523530
goto bad;
524531

525532
for (i = 0; i < nel; i++) {
526-
rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL);
533+
rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL, false);
527534
if (rc) {
528535
if (rc == -ENOMEM)
529536
pr_err("SELinux: avtab: out of memory\n");

security/selinux/ss/avtab.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct policydb;
108108
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
109109
int (*insert)(struct avtab *a, const struct avtab_key *k,
110110
const struct avtab_datum *d, void *p),
111-
void *p);
111+
void *p, bool conditional);
112112

113113
int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
114114
int avtab_write_item(struct policydb *p, const struct avtab_node *cur,

security/selinux/ss/conditional.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static int cond_read_av_list(struct policydb *p, void *fp,
349349
for (i = 0; i < len; i++) {
350350
data.dst = &list->nodes[i];
351351
rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
352-
&data);
352+
&data, true);
353353
if (rc) {
354354
kfree(list->nodes);
355355
list->nodes = NULL;

security/selinux/ss/policydb.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ static const struct policydb_compat_info policydb_compat[] = {
155155
.sym_num = SYM_NUM,
156156
.ocon_num = OCON_NUM,
157157
},
158+
{
159+
.version = POLICYDB_VERSION_COND_XPERMS,
160+
.sym_num = SYM_NUM,
161+
.ocon_num = OCON_NUM,
162+
},
158163
};
159164

160165
static const struct policydb_compat_info *

security/selinux/ss/services.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ static void avd_init(struct selinux_policy *policy, struct av_decision *avd)
946946
}
947947

948948
static void update_xperms_extended_data(u8 specified,
949-
struct extended_perms_data *from,
949+
const struct extended_perms_data *from,
950950
struct extended_perms_data *xp_data)
951951
{
952952
unsigned int i;
@@ -967,6 +967,8 @@ static void update_xperms_extended_data(u8 specified,
967967
void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
968968
struct avtab_node *node)
969969
{
970+
u16 specified;
971+
970972
switch (node->datum.u.xperms->specified) {
971973
case AVTAB_XPERMS_IOCTLFUNCTION:
972974
case AVTAB_XPERMS_NLMSG:
@@ -982,17 +984,19 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
982984
BUG();
983985
}
984986

985-
if (node->key.specified == AVTAB_XPERMS_ALLOWED) {
987+
specified = node->key.specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD);
988+
989+
if (specified == AVTAB_XPERMS_ALLOWED) {
986990
xpermd->used |= XPERMS_ALLOWED;
987991
update_xperms_extended_data(node->datum.u.xperms->specified,
988992
&node->datum.u.xperms->perms,
989993
xpermd->allowed);
990-
} else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) {
994+
} else if (specified == AVTAB_XPERMS_AUDITALLOW) {
991995
xpermd->used |= XPERMS_AUDITALLOW;
992996
update_xperms_extended_data(node->datum.u.xperms->specified,
993997
&node->datum.u.xperms->perms,
994998
xpermd->auditallow);
995-
} else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) {
999+
} else if (specified == AVTAB_XPERMS_DONTAUDIT) {
9961000
xpermd->used |= XPERMS_DONTAUDIT;
9971001
update_xperms_extended_data(node->datum.u.xperms->specified,
9981002
&node->datum.u.xperms->perms,

0 commit comments

Comments
 (0)