[Bug 193584] New: [autofs] problem when resolving maps with partial path matches

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Fri Sep 12 12:22:39 UTC 2014


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193584

            Bug ID: 193584
           Summary: [autofs] problem when resolving maps with partial path
                    matches
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: Needs Triage
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: bz at FreeBSD.org

When an indirect map returns:

...
/auto/foo/www
/auto/foo/www-bar
/auto/foo/www-baz

and we are looking up www-bar the strncmp in node_find() will match on www
already and try to mount that;  if parts of the path are expanded from the key
facilitating the & we might try to mount

/auto/foo/www-baz from filer:/totally/different/path/&

I have tried to figure out how to fix that strncmp without much luck running
into other assertion failures due to path being an empty string for the initial
map lookup it seemed, so I added some extra comparison to the child loop, which
should catch all cases still but handling a possible trailing / makes it look
ugly.  Trying to avoid a possible strdup() failure, I am using two strlen() and
a strncmp() on the longer path; obviously one could also check the lens to be
equal first.

Here's a part of the diff with all debugging etc. in it still:

@@ -674,19 +674,41 @@ node_find(struct node *node, const char *path)
     struct node *child, *found;
     char *tmp;

-    //log_debugx("looking up %s in %s", path, node->n_key);
+    log_debugx("looking up %s in %s", path, node->n_key);

     tmp = node_path(node);
+#if 1
     if (strncmp(tmp, path, strlen(tmp)) != 0) {
+#else
+    log_debugx("comparing '%s' '%s' %zu %zu", tmp, path, strlen(path),
strlen(tmp));
+    if (strlen(tmp) != 0 && strncmp(tmp, path, strlen(tmp)) != 0) {
+#endif
         free(tmp);
         return (NULL);
     }
     free(tmp);
+    node_print(node);

     TAILQ_FOREACH(child, &node->n_children, n_next) {
         found = node_find(child, path);
-        if (found != NULL)
-            return (found);
+        if (found != NULL) {
+            size_t pl, tl;
+
+            tmp = node_path(found);
+            log_debugx("found candidate %s %s %s", tmp, path, found->n_key);
+            /* node_path() already removes a possible trainling '/'. */
+            tl = strlen(tmp);
+            pl = strlen(path);
+            if (path[pl-1] == '/')
+                pl--;
+            pl = (pl > tl) ? pl : tl;
+            if (strncmp(tmp, path, pl) == 0) {
+                log_debugx("found match %s %s %s %zu", tmp, path,
found->n_key, pl);
+                free(tmp);
+                return (found);
+            }
+            free(tmp);
+        }
     }

     return (node);

I am sure there is a better, proper solution and I am willing to test.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list