Having a trailing slash on an selabel file lookup can yield a different result. For example: /path/foo(/.*)? user:role:type1 /path/foo/bar -d user:role:type2 A lookup of "/path/foo/bar/" would yield user:role:type1 instead of user:role:type2, which is unlike typical Linux behaviors where trailing slashes are ignored. Many callers already strip the trailing slash before the lookup or users revise the file contexts to work around this. Fix it comprehensively. Signed-off-by: Chris PeBenito <chpebeni@xxxxxxxxxxxxxxxxxxx> --- libselinux/src/label_file.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c index 412904d1..42d9d485 100644 --- a/libselinux/src/label_file.c +++ b/libselinux/src/label_file.c @@ -853,7 +853,7 @@ static const struct spec **lookup_all(struct selabel_handle *rec, { struct saved_data *data = (struct saved_data *)rec->data; struct spec *spec_arr = data->spec_arr; - int i, rc, file_stem; + int i, rc, file_stem, len; mode_t mode = (mode_t)type; char *clean_key = NULL; const char *prev_slash, *next_slash; @@ -894,6 +894,22 @@ static const struct spec **lookup_all(struct selabel_handle *rec, key = clean_key; } + /* remove trailing slash */ + len = strlen(key); + if (key[len - 1] == '/') { + /* reuse clean_key from above if available */ + if (!clean_key) { + clean_key = (char *) malloc(len); + if (!clean_key) + goto finish; + + strncpy(clean_key, key, len - 1); + } + + clean_key[len - 1] = '\0'; + key = clean_key; + } + sub = selabel_sub_key(data, key); if (sub) key = sub; -- 2.26.2