aboutsummaryrefslogtreecommitdiffstats
path: root/main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch')
-rw-r--r--main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch b/main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch
new file mode 100644
index 0000000000..e6f372b758
--- /dev/null
+++ b/main/nfs-utils/0001-mountd-Fix-is_subdirectory-again.patch
@@ -0,0 +1,81 @@
+From 23d3980b6cfea4e9056d9b7b81e48b4fefc645e0 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Tue, 7 May 2013 11:46:18 -0400
+Subject: [PATCH] mountd: Fix is_subdirectory again
+
+The problem was that is_subdirectory() would also succeed if the two
+directories were the same. This is needed for path_matches() which
+needs to see if the child is same-or-descendant.
+
+So this patch rearranges path_matches() to do the "are they the same"
+test itself and only bother with is_subdirectory() if it they are not
+the same.
+
+So now is_subdirectory() can be strict, and so can be usable for
+subexport(), which needs a strong 'in subdirectory - not the same' test.
+
+Acked-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+---
+ utils/mountd/cache.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
+index 737927c..517aa62 100644
+--- a/utils/mountd/cache.c
++++ b/utils/mountd/cache.c
+@@ -347,20 +347,26 @@ static char *next_mnt(void **v, char *p)
+
+ static int is_subdirectory(char *child, char *parent)
+ {
++ /* Check is child is strictly a subdirectory of
++ * parent or a more distant descendant.
++ */
+ size_t l = strlen(parent);
+
+- if (strcmp(parent, "/") == 0)
++ if (strcmp(parent, "/") == 0 && child[1] != 0)
+ return 1;
+
+- return strcmp(child, parent) == 0
+- || (strncmp(child, parent, l) == 0 && child[l] == '/');
++ return (strncmp(child, parent, l) == 0 && child[l] == '/');
+ }
+
+ static int path_matches(nfs_export *exp, char *path)
+ {
+- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+- return is_subdirectory(path, exp->m_export.e_path);
+- return strcmp(path, exp->m_export.e_path) == 0;
++ /* Does the path match the export? I.e. is it an
++ * exact match, or does the export have CROSSMOUNT, and path
++ * is a descendant?
++ */
++ return strcmp(path, exp->m_export.e_path) == 0
++ || ((exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
++ && is_subdirectory(path, exp->m_export.e_path));
+ }
+
+ static int
+@@ -369,15 +375,13 @@ export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
+ return path_matches(exp, path) && client_matches(exp, dom, ai);
+ }
+
+-/* True iff e1 is a child of e2 and e2 has crossmnt set: */
++/* True iff e1 is a child of e2 (or descendant) and e2 has crossmnt set: */
+ static bool subexport(struct exportent *e1, struct exportent *e2)
+ {
+ char *p1 = e1->e_path, *p2 = e2->e_path;
+- size_t l2 = strlen(p2);
+
+ return e2->e_flags & NFSEXP_CROSSMOUNT
+- && strncmp(p1, p2, l2) == 0
+- && p1[l2] == '/';
++ && is_subdirectory(p1, p2);
+ }
+
+ struct parsed_fsid {
+--
+1.8.3.2
+