From 8ec2f2bde7c53834a304bcdc68e84d8c7a748ca4 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 17 Jun 2018 21:48:40 -0400 Subject: [PATCH] src/libadacl.c: fix handling of "./" and "../" as paths. The recent fixes for the paths "." and ".." ignored the other obvious cases, where those paths have a trailing slash appended. The trailing slash is now handled by comparing the basename of the path against "." and ".." rather than the path itself. This allows the test suite, which now contains tests for "./" and "../", to pass. --- src/libadacl.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/libadacl.c b/src/libadacl.c index 8ff0c17..d2462c8 100644 --- a/src/libadacl.c +++ b/src/libadacl.c @@ -1004,14 +1004,23 @@ int apply_default_acl(const char* path, bool recursive) { } char* parent = dirname(dirname_path_copy); + basename_path_copy = strdup(path); + if (basename_path_copy == NULL) { + perror("apply_default_acl (strdup)"); + result = ACL_ERROR; + goto cleanup; + } + char* child = basename(basename_path_copy); + /* Just kidding, if the path is "." or "..", then dirname will do * the wrong thing and give us "." as its parent, too. So, we handle - * those as special cases. + * those as special cases. We use "child" instead of "path" here to + * catch things like "./" and "../" */ - bool path_is_dots = strcmp(path, ".") == 0 || strcmp(path, "..") == 0; + bool path_is_dots = strcmp(child, ".") == 0 || strcmp(child, "..") == 0; char dots_parent[6] = "../"; if (path_is_dots) { - parent = strcat(dots_parent, path); + parent = strcat(dots_parent, child); } parent_fd = safe_open(parent, O_DIRECTORY | O_NOFOLLOW); @@ -1031,24 +1040,19 @@ int apply_default_acl(const char* path, bool recursive) { } /* We already obtained the parent fd safely, so if we use the - basename of path here instead of the full thing, then we can get - away with using openat() and spare ourselves the slowness of - another safe_open(). */ - basename_path_copy = strdup(path); - if (basename_path_copy == NULL) { - perror("apply_default_acl (strdup)"); - result = ACL_ERROR; - goto cleanup; - } - - /* If the basename is "." or "..", then we don't want to open it - relative to the parent_fd, so we need another special case for - those paths. */ + * basename of path here instead of the full thing, then we can get + * away with using openat() and spare ourselves the slowness of + * another safe_open(). + * + * Note that if the basename is "." or "..", then we don't want to + * open it relative to the parent_fd, so we need another special + * case for those paths here. + */ if (path_is_dots) { - fd = open(path, O_NOFOLLOW); + fd = open(child, O_NOFOLLOW); } else { - fd = openat(parent_fd, basename(basename_path_copy), O_NOFOLLOW); + fd = openat(parent_fd, child, O_NOFOLLOW); } if (fd == OPEN_ERROR) { if (errno == ELOOP || errno == ENOTDIR) { -- 2.44.2