[PATCH] Remove duplicate slashes in paths in selabel_lookup
This patch simply removes duplicate slashes (meaning "//") from
pathnames passed into selabel_lookup. It does not do a full
realpath() calculation (e.g. following symlinks, etc.), as the
client should really do that before calling into libselinux.
Signed-off-by: Chad Sellers <csellers@tresys.com>
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 509b033..937e509 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -584,13 +584,34 @@
spec_t *spec_arr = data->spec_arr;
int i, rc, file_stem;
mode_t mode = (mode_t)type;
- const char *buf = key;
+ const char *buf;
+ struct selabel_lookup_rec *ret = NULL;
+ char *clean_key = NULL;
+ const char *prev_slash, *next_slash;
+ unsigned int sofar = 0;
if (!data->nspec) {
errno = ENOENT;
- return NULL;
+ goto finish;
}
+ /* Remove duplicate slashes */
+ if ((next_slash = strstr(key, "//"))) {
+ clean_key = malloc(strlen(key) + 1);
+ if (!clean_key)
+ goto finish;
+ prev_slash = key;
+ while (next_slash) {
+ memcpy(clean_key + sofar, prev_slash, next_slash - prev_slash);
+ sofar += next_slash - prev_slash;
+ prev_slash = next_slash + 1;
+ next_slash = strstr(prev_slash, "//");
+ }
+ strcpy(clean_key + sofar, prev_slash);
+ key = clean_key;
+ }
+
+ buf = key;
file_stem = find_stem_from_file(data, &buf);
mode &= S_IFMT;
@@ -608,7 +629,7 @@
&& (!mode || !spec_arr[i].mode
|| mode == spec_arr[i].mode)) {
if (compile_regex(data, &spec_arr[i], NULL) < 0)
- return NULL;
+ goto finish;
if (spec_arr[i].stem_id == -1)
rc = regexec(&spec_arr[i].regex, key, 0, 0, 0);
else
@@ -621,17 +642,21 @@
if (rc == REG_NOMATCH)
continue;
/* else it's an error */
- return NULL;
+ goto finish;
}
}
if (i < 0 || strcmp(spec_arr[i].lr.ctx_raw, "<<none>>") == 0) {
/* No matching specification. */
errno = ENOENT;
- return NULL;
+ goto finish;
}
- return &spec_arr[i].lr;
+ ret = &spec_arr[i].lr;
+
+finish:
+ free(clean_key);
+ return ret;
}
static void stats(struct selabel_handle *rec)