libselinux: Fix property processing and cleanup formatting
Fix memory issues flagged by valgrind. These changes bring the property service in line with Android [1] V2 reverts to original upstream %u when logging errors. Android needs these corrections also. [1] https://android-review.googlesource.com/#/c/153580/ Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
This commit is contained in:
parent
8282ec48d2
commit
9eae65894a
1 changed files with 33 additions and 27 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Property Service contexts backend for labeling Android
|
||||
* Property Service contexts backend for labeling Android
|
||||
* property keys
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
/* A property security context specification. */
|
||||
typedef struct spec {
|
||||
struct selabel_lookup_rec lr; /* holds contexts for lookup result */
|
||||
char *property_key; /* property key string */
|
||||
char *property_key; /* property key string */
|
||||
} spec_t;
|
||||
|
||||
/* Our stored configuration */
|
||||
|
@ -56,21 +56,23 @@ static int nodups_specs(struct saved_data *data, const char *path)
|
|||
for (ii = 0; ii < data->nspec; ii++) {
|
||||
curr_spec = &spec_arr[ii];
|
||||
for (jj = ii + 1; jj < data->nspec; jj++) {
|
||||
if (!strcmp(spec_arr[jj].property_key, curr_spec->property_key)) {
|
||||
if (!strcmp(spec_arr[jj].property_key,
|
||||
curr_spec->property_key)) {
|
||||
rc = -1;
|
||||
errno = EINVAL;
|
||||
if (strcmp(spec_arr[jj].lr.ctx_raw, curr_spec->lr.ctx_raw)) {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: Multiple different specifications for %s (%s and %s).\n",
|
||||
path,
|
||||
curr_spec->property_key,
|
||||
spec_arr[jj].lr.ctx_raw,
|
||||
curr_spec->lr.ctx_raw);
|
||||
if (strcmp(spec_arr[jj].lr.ctx_raw,
|
||||
curr_spec->lr.ctx_raw)) {
|
||||
selinux_log
|
||||
(SELINUX_ERROR,
|
||||
"%s: Multiple different specifications for %s (%s and %s).\n",
|
||||
path, curr_spec->property_key,
|
||||
spec_arr[jj].lr.ctx_raw,
|
||||
curr_spec->lr.ctx_raw);
|
||||
} else {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: Multiple same specifications for %s.\n",
|
||||
path,
|
||||
curr_spec->property_key);
|
||||
selinux_log
|
||||
(SELINUX_ERROR,
|
||||
"%s: Multiple same specifications for %s.\n",
|
||||
path, curr_spec->property_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,21 +97,24 @@ static int process_line(struct selabel_handle *rec,
|
|||
selinux_log(SELINUX_WARNING,
|
||||
"%s: line %u is missing fields, skipping\n", path,
|
||||
lineno);
|
||||
free(prop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pass == 1) {
|
||||
if (pass == 0) {
|
||||
free(prop);
|
||||
free(context);
|
||||
} else if (pass == 1) {
|
||||
/* On the second pass, process and store the specification in spec. */
|
||||
spec_arr[nspec].property_key = strdup(prop);
|
||||
spec_arr[nspec].property_key = prop;
|
||||
if (!spec_arr[nspec].property_key) {
|
||||
selinux_log(SELINUX_WARNING,
|
||||
"%s: out of memory at line %u on prop %s\n",
|
||||
path, lineno, prop);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
spec_arr[nspec].lr.ctx_raw = strdup(context);
|
||||
spec_arr[nspec].lr.ctx_raw = context;
|
||||
if (!spec_arr[nspec].lr.ctx_raw) {
|
||||
selinux_log(SELINUX_WARNING,
|
||||
"%s: out of memory at line %u on context %s\n",
|
||||
|
@ -149,7 +154,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!path)
|
||||
if (!path)
|
||||
return -1;
|
||||
|
||||
/* Open the specification file. */
|
||||
|
@ -164,17 +169,18 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
|
|||
|
||||
/*
|
||||
* Two passes of the specification file. First is to get the size.
|
||||
* After the first pass, the spec array is malloced to the appropriate
|
||||
* size. Second pass is to populate the spec array and check for
|
||||
* After the first pass, the spec array is malloced to the appropriate
|
||||
* size. Second pass is to populate the spec array and check for
|
||||
* dups.
|
||||
*/
|
||||
maxnspec = UINT_MAX / sizeof(spec_t);
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
data->nspec = 0;
|
||||
|
||||
while (fgets(line_buf, sizeof line_buf - 1, fp)
|
||||
while (fgets(line_buf, sizeof(line_buf) - 1, fp)
|
||||
&& data->nspec < maxnspec) {
|
||||
if (process_line(rec, path, line_buf, pass, ++lineno) != 0)
|
||||
if (process_line(rec, path, line_buf, pass, ++lineno)
|
||||
!= 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -186,7 +192,6 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
|
|||
}
|
||||
|
||||
if (pass == 0) {
|
||||
|
||||
if (data->nspec == 0) {
|
||||
status = 0;
|
||||
goto finish;
|
||||
|
@ -234,7 +239,7 @@ static void closef(struct selabel_handle *rec)
|
|||
|
||||
static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
|
||||
const char *key,
|
||||
int __attribute__ ((unused)) type)
|
||||
int __attribute__((unused)) type)
|
||||
{
|
||||
struct saved_data *data = (struct saved_data *)rec->data;
|
||||
spec_t *spec_arr = data->spec_arr;
|
||||
|
@ -267,12 +272,13 @@ finish:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void stats(struct selabel_handle __attribute__ ((unused)) * rec)
|
||||
static void stats(struct selabel_handle __attribute__((unused)) *rec)
|
||||
{
|
||||
selinux_log(SELINUX_WARNING, "'stats' functionality not implemented.\n");
|
||||
}
|
||||
|
||||
int selabel_property_init(struct selabel_handle *rec, struct selinux_opt *opts,
|
||||
int selabel_property_init(struct selabel_handle *rec,
|
||||
struct selinux_opt *opts,
|
||||
unsigned nopts)
|
||||
{
|
||||
struct saved_data *data;
|
||||
|
|
Loading…
Reference in a new issue