diff mbox series

[1/1] libselinux: Remove trailing slash on selabel_file lookups.

Message ID 20200820154726.210419-1-chpebeni@linux.microsoft.com (mailing list archive)
State Superseded
Headers show
Series [1/1] libselinux: Remove trailing slash on selabel_file lookups. | expand

Commit Message

Chris PeBenito Aug. 20, 2020, 3:47 p.m. UTC
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@linux.microsoft.com>
---
 libselinux/src/label_file.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Comments

Stephen Smalley Aug. 24, 2020, 1:35 p.m. UTC | #1
On Thu, Aug 20, 2020 at 11:51 AM Chris PeBenito
<chpebeni@linux.microsoft.com> wrote:
>
> 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@linux.microsoft.com>
> ---
>  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;

size_t 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] == '/') {

What if len == 0?

> +               /* 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
>
diff mbox series

Patch

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;