]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2023-34968: lib: Move subdir_of() to source3/lib/util_path.c
authorVolker Lendecke <vl@samba.org>
Sat, 15 Oct 2022 11:29:14 +0000 (13:29 +0200)
committerJule Anger <janger@samba.org>
Fri, 14 Jul 2023 13:16:29 +0000 (15:16 +0200)
Make it available for other components

Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207
Signed-off-by: Volker Lendecke <vl@samba.org>
(backported from commit d905dbddf8d2655e6c91752b750cbe9c15837ee5)
[slow@samba.org: subdir_of() didn't exist yet in 4.16 so this just adds it]

source3/lib/util_path.c
source3/lib/util_path.h

index c34b734384cfc75fd7244fc474d5ae3622b43cbb..e6bed7245517f3d95ec833c85da99a93d5066995 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "replace.h"
 #include <talloc.h>
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
 #include "lib/util/samba_util.h"
 #include "lib/util_path.h"
 
@@ -210,3 +212,53 @@ char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *pathname_in)
        *p++ = '\0';
        return pathname;
 }
+
+/*
+ * Take two absolute paths, figure out if "subdir" is a proper
+ * subdirectory of "parent". Return the component relative to the
+ * "parent" without the potential "/". Take care of "parent"
+ * possibly ending in "/".
+ */
+bool subdir_of(const char *parent,
+              size_t parent_len,
+              const char *subdir,
+              const char **_relative)
+{
+       const char *relative = NULL;
+       bool matched;
+
+       SMB_ASSERT(parent[0] == '/');
+       SMB_ASSERT(subdir[0] == '/');
+
+       if (parent_len == 1) {
+               /*
+                * Everything is below "/"
+                */
+               *_relative = subdir+1;
+               return true;
+       }
+
+       if (parent[parent_len-1] == '/') {
+               parent_len -= 1;
+       }
+
+       matched = (strncmp(subdir, parent, parent_len) == 0);
+       if (!matched) {
+               return false;
+       }
+
+       relative = &subdir[parent_len];
+
+       if (relative[0] == '\0') {
+               *_relative = relative; /* nothing left */
+               return true;
+       }
+
+       if (relative[0] == '/') {
+               /* End of parent must match a '/' in subdir. */
+               *_relative = relative+1;
+               return true;
+       }
+
+       return false;
+}
index 3e7d04de5507d7324e94985f1630e6d02a50d500..0ea508bf5bbc854ea4e63007bbbd212e3b885355 100644 (file)
@@ -31,5 +31,9 @@ char *lock_path(TALLOC_CTX *mem_ctx, const char *name);
 char *state_path(TALLOC_CTX *mem_ctx, const char *name);
 char *cache_path(TALLOC_CTX *mem_ctx, const char *name);
 char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path);
+bool subdir_of(const char *parent,
+              size_t parent_len,
+              const char *subdir,
+              const char **_relative);
 
 #endif