mirror of
https://github.com/SELinuxProject/selinux
synced 2025-01-11 07:59:26 +00:00
libsepol: avoid fixed sized format buffer for xperms
An extended access vector rule can consist of many individual ranges of permissions. Use a dynamically growing sized buffer for formatting such rules instead of a static buffer to avoid write failures due to truncations. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
parent
285d7cc81b
commit
fdb536f38d
@ -347,6 +347,7 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
|
|||||||
display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
|
display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
|
||||||
} else if (avrule->specified & AVRULE_XPERMS) {
|
} else if (avrule->specified & AVRULE_XPERMS) {
|
||||||
avtab_extended_perms_t xperms;
|
avtab_extended_perms_t xperms;
|
||||||
|
char *perms;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLFUNCTION)
|
if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLFUNCTION)
|
||||||
@ -362,7 +363,13 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
|
|||||||
for (i = 0; i < EXTENDED_PERMS_LEN; i++)
|
for (i = 0; i < EXTENDED_PERMS_LEN; i++)
|
||||||
xperms.perms[i] = avrule->xperms->perms[i];
|
xperms.perms[i] = avrule->xperms->perms[i];
|
||||||
|
|
||||||
fprintf(fp, "%s", sepol_extended_perms_to_string(&xperms));
|
perms = sepol_extended_perms_to_string(&xperms);
|
||||||
|
if (!perms) {
|
||||||
|
fprintf(fp, " ERROR: failed to format xperms\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(fp, "%s", perms);
|
||||||
|
free(perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, ";\n");
|
fprintf(fp, ";\n");
|
||||||
|
@ -196,6 +196,8 @@ static int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t wha
|
|||||||
fprintf(fp, ";\n");
|
fprintf(fp, ";\n");
|
||||||
}
|
}
|
||||||
} else if (key->specified & AVTAB_XPERMS) {
|
} else if (key->specified & AVTAB_XPERMS) {
|
||||||
|
char *perms;
|
||||||
|
|
||||||
if (key->specified & AVTAB_XPERMS_ALLOWED)
|
if (key->specified & AVTAB_XPERMS_ALLOWED)
|
||||||
fprintf(fp, "allowxperm ");
|
fprintf(fp, "allowxperm ");
|
||||||
else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
|
else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
|
||||||
@ -203,7 +205,13 @@ static int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t wha
|
|||||||
else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
|
else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
|
||||||
fprintf(fp, "dontauditxperm ");
|
fprintf(fp, "dontauditxperm ");
|
||||||
render_key(key, p, fp);
|
render_key(key, p, fp);
|
||||||
fprintf(fp, "%s;\n", sepol_extended_perms_to_string(datum->xperms));
|
perms = sepol_extended_perms_to_string(datum->xperms);
|
||||||
|
if (!perms) {
|
||||||
|
fprintf(fp, " ERROR: failed to format xperms\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(fp, "%s;\n", perms);
|
||||||
|
free(perms);
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp, " ERROR: no valid rule type specified\n");
|
fprintf(fp, " ERROR: no valid rule type specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -178,15 +178,20 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle,
|
|||||||
rc = check_extended_permissions(avrule->xperms, xperms);
|
rc = check_extended_permissions(avrule->xperms, xperms);
|
||||||
/* failure on the extended permission check_extended_permissions */
|
/* failure on the extended permission check_extended_permissions */
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
char *permstring;
|
||||||
|
|
||||||
extended_permissions_violated(&error, avrule->xperms, xperms);
|
extended_permissions_violated(&error, avrule->xperms, xperms);
|
||||||
|
permstring = sepol_extended_perms_to_string(&error);
|
||||||
|
|
||||||
ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
|
ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
|
||||||
"allowxperm %s %s:%s %s;",
|
"allowxperm %s %s:%s %s;",
|
||||||
avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
|
avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
|
||||||
p->p_type_val_to_name[i],
|
p->p_type_val_to_name[i],
|
||||||
p->p_type_val_to_name[j],
|
p->p_type_val_to_name[j],
|
||||||
p->p_class_val_to_name[curperm->tclass - 1],
|
p->p_class_val_to_name[curperm->tclass - 1],
|
||||||
sepol_extended_perms_to_string(&error));
|
permstring ?: "<format-failure>");
|
||||||
|
|
||||||
|
free(permstring);
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1683,7 +1683,7 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
|
|||||||
uint32_t data = datum->data;
|
uint32_t data = datum->data;
|
||||||
type_datum_t *type;
|
type_datum_t *type;
|
||||||
const char *flavor, *src, *tgt, *class, *perms, *new;
|
const char *flavor, *src, *tgt, *class, *perms, *new;
|
||||||
char *rule = NULL;
|
char *rule = NULL, *permstring;
|
||||||
|
|
||||||
switch (0xFFF & key->specified) {
|
switch (0xFFF & key->specified) {
|
||||||
case AVTAB_ALLOWED:
|
case AVTAB_ALLOWED:
|
||||||
@ -1738,13 +1738,14 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
|
|||||||
rule = create_str("%s %s %s:%s { %s };", 5,
|
rule = create_str("%s %s %s:%s { %s };", 5,
|
||||||
flavor, src, tgt, class, perms+1);
|
flavor, src, tgt, class, perms+1);
|
||||||
} else if (key->specified & AVTAB_XPERMS) {
|
} else if (key->specified & AVTAB_XPERMS) {
|
||||||
perms = sepol_extended_perms_to_string(datum->xperms);
|
permstring = sepol_extended_perms_to_string(datum->xperms);
|
||||||
if (perms == NULL) {
|
if (permstring == NULL) {
|
||||||
ERR(NULL, "Failed to generate extended permission string");
|
ERR(NULL, "Failed to generate extended permission string");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = create_str("%s %s %s:%s %s;", 5, flavor, src, tgt, class, perms);
|
rule = create_str("%s %s %s:%s %s;", 5, flavor, src, tgt, class, permstring);
|
||||||
|
free(permstring);
|
||||||
} else {
|
} else {
|
||||||
new = pdb->p_type_val_to_name[data - 1];
|
new = pdb->p_type_val_to_name[data - 1];
|
||||||
|
|
||||||
|
@ -132,21 +132,32 @@ char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
|
|||||||
uint16_t low_bit;
|
uint16_t low_bit;
|
||||||
uint16_t low_value;
|
uint16_t low_value;
|
||||||
unsigned int bit;
|
unsigned int bit;
|
||||||
unsigned int in_range = 0;
|
unsigned int in_range;
|
||||||
static char xpermsbuf[2048];
|
char *buffer = NULL, *p;
|
||||||
char *p;
|
int len;
|
||||||
int len, xpermslen = 0;
|
size_t remaining, size = 128;
|
||||||
xpermsbuf[0] = '\0';
|
|
||||||
p = xpermsbuf;
|
|
||||||
|
|
||||||
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
||||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
|
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "ioctl { ");
|
retry:
|
||||||
p += len;
|
size *= 2;
|
||||||
xpermslen += len;
|
if (size == 0)
|
||||||
|
goto err;
|
||||||
|
p = realloc(buffer, size);
|
||||||
|
if (!p)
|
||||||
|
goto err;
|
||||||
|
buffer = p;
|
||||||
|
remaining = size;
|
||||||
|
|
||||||
|
len = snprintf(p, remaining, "ioctl { ");
|
||||||
|
if (len < 0 || (size_t)len >= remaining)
|
||||||
|
goto err;
|
||||||
|
p += len;
|
||||||
|
remaining -= len;
|
||||||
|
|
||||||
|
in_range = 0;
|
||||||
for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
|
for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
|
||||||
if (!xperm_test(bit, xperms->perms))
|
if (!xperm_test(bit, xperms->perms))
|
||||||
continue;
|
continue;
|
||||||
@ -165,35 +176,43 @@ char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
|
|||||||
value = xperms->driver<<8 | bit;
|
value = xperms->driver<<8 | bit;
|
||||||
if (in_range) {
|
if (in_range) {
|
||||||
low_value = xperms->driver<<8 | low_bit;
|
low_value = xperms->driver<<8 | low_bit;
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, value);
|
len = snprintf(p, remaining, "0x%hx-0x%hx ", low_value, value);
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx ", value);
|
len = snprintf(p, remaining, "0x%hx ", value);
|
||||||
}
|
}
|
||||||
} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
|
} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
|
||||||
value = bit << 8;
|
value = bit << 8;
|
||||||
if (in_range) {
|
if (in_range) {
|
||||||
low_value = low_bit << 8;
|
low_value = low_bit << 8;
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
|
len = snprintf(p, remaining, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
|
len = snprintf(p, remaining, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
|
if (len < 0)
|
||||||
return NULL;
|
goto err;
|
||||||
|
if ((size_t) len >= remaining)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
p += len;
|
p += len;
|
||||||
xpermslen += len;
|
remaining -= len;
|
||||||
if (in_range)
|
if (in_range)
|
||||||
in_range = 0;
|
in_range = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "}");
|
len = snprintf(p, remaining, "}");
|
||||||
if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
|
if (len < 0)
|
||||||
return NULL;
|
goto err;
|
||||||
|
if ((size_t) len >= remaining)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
return xpermsbuf;
|
return buffer;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user