bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] fix the trailing slash issue in dir_lookup calls


From: Flavio Cruz
Subject: [PATCH] fix the trailing slash issue in dir_lookup calls
Date: Sun, 3 Jan 2016 01:14:40 +0100
User-agent: Mutt/1.5.24 (2015-08-30)

Hello

I've played around with the code in order to fix the trailing slash
issue. When we do a file name lookup with a trailing '/' and the final
component is a translator, the '/' is not sent to the translator since
glibc strips the '/' before calling dir_lookup on the translator.  This
patches fixes this by changing glibc, libnetfs and libdiskfs. The change
in glibc is not a big issue since must translators already remove
leading slashes. In libdiskfs and libnetfs's dir_lookup, 'mustbedir'
must be checked (it indicates that there is a trailing slash) and is
used to add a '/' to retry_name whenever needed.  At the end of the day,
this patch makes things like 'ls /dev/null/' to return 'invalid
directory'.

I've been able to boot the system using this patch and everything looks
good so far, however, I'm asking you for initial comments and for
anything else I might be missing.

Best
Flavio

---

diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 75df9b8..be0f88c 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -161,7 +161,9 @@ diskfs_S_dir_lookup (struct protid *dircred,
                  *retry = FS_RETRY_REAUTH;
                  *returned_port = dircred->po->shadow_root_parent;
                  *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
-                 if (! lastcomp)
+                 if (lastcomp && mustbedir) /* Trailing slash.  */
+                    strcpy (retryname, "/");
+                 else if (!lastcomp)
                    strcpy (retryname, nextname);
                  err = 0;
                  goto out;
@@ -175,7 +177,9 @@ diskfs_S_dir_lookup (struct protid *dircred,
              *retry = FS_RETRY_REAUTH;
              *returned_port = dircred->po->root_parent;
              *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
-             if (!lastcomp)
+             if (lastcomp && mustbedir) /* Trailing slash.  */
+                strcpy (retryname, "/");
+             else if (!lastcomp)
                strcpy (retryname, nextname);
              err = 0;
              goto out;
@@ -213,7 +217,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
 
       /* If this is translated, start the translator (if necessary)
         and return.  */
-      if ((((flags & O_NOTRANS) == 0) || !lastcomp)
+      if ((((flags & O_NOTRANS) == 0) || !lastcomp || mustbedir)
          && ((np->dn_stat.st_mode & S_IPTRANS)
              || S_ISFIFO (np->dn_stat.st_mode)
              || S_ISCHR (np->dn_stat.st_mode)
@@ -290,7 +294,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
 
          err = fshelp_fetch_root (&np->transbox, dircred->po,
                                     dirport, dircred->user,
-                                    lastcomp ? flags : 0,
+                                    (lastcomp && !mustbedir) ? flags : 0,
                                     ((np->dn_stat.st_mode & S_IPTRANS)
                                      ? _diskfs_translator_callback1
                                      : short_circuited_callback1),
@@ -304,11 +308,16 @@ diskfs_S_dir_lookup (struct protid *dircred,
          if (err != ENOENT)
            {
              *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
-             if (!lastcomp && !err)
-               {
+              if (!err)
+                {
                  char *end = strchr (retryname, '\0');
-                 *end++ = '/';
-                 strcpy (end, nextname);
+                  if (mustbedir)
+                    *end++ = '/'; /* Trailing slash.  */
+                  else if (!lastcomp) {
+                    if (end != retryname)
+                      *end++ = '/';
+                    strcpy (end, nextname);
+                  }
                }
 
              if (register_translator)
diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index 8b8cd6e..4b68144 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -128,7 +128,9 @@ netfs_S_dir_lookup (struct protid *diruser,
            *do_retry = FS_RETRY_REAUTH;
            *retry_port = diruser->po->shadow_root_parent;
            *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
-           if (! lastcomp)
+           if (lastcomp && mustbedir) /* Trailing slash.  */
+             strcpy (retry_name, "/");
+           else if (!lastcomp)
              strcpy (retry_name, nextname);
            error = 0;
            pthread_mutex_unlock (&dnp->lock);
@@ -142,7 +144,9 @@ netfs_S_dir_lookup (struct protid *diruser,
            *do_retry = FS_RETRY_REAUTH;
            *retry_port = diruser->po->root_parent;
            *retry_port_type = MACH_MSG_TYPE_COPY_SEND;
-           if (!lastcomp)
+           if (lastcomp && mustbedir) /* Trailing slash.  */
+             strcpy (retry_name, "/");
+            else if (!lastcomp)
              strcpy (retry_name, nextname);
            error = 0;
            pthread_mutex_unlock (&dnp->lock);
@@ -194,7 +198,7 @@ netfs_S_dir_lookup (struct protid *diruser,
       if (error)
        goto out;
 
-      if ((((flags & O_NOTRANS) == 0) || !lastcomp)
+      if ((((flags & O_NOTRANS) == 0) || !lastcomp || mustbedir)
          && ((np->nn_translated & S_IPTRANS)
              || S_ISFIFO (np->nn_translated)
              || S_ISCHR (np->nn_translated)
@@ -290,8 +294,14 @@ netfs_S_dir_lookup (struct protid *diruser,
              *retry_port_type = MACH_MSG_TYPE_MOVE_SEND;
              if (!lastcomp && !error)
                {
-                 strcat (retry_name, "/");
-                 strcat (retry_name, nextname);
+                 char *end = strchr (retry_name, '\0');
+                  if (mustbedir)
+                    *end++ = '/'; /* Trailing slash.  */
+                  else if (!lastcomp) {
+                    if (end != retry_name)
+                      *end++ = '/';
+                    strcpy (end, nextname);
+                  }
                }
 
              if (register_translator)
diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c
index f633e57..b221db8 100644
--- a/hurd/lookup-retry.c
+++ b/hurd/lookup-retry.c
@@ -62,7 +62,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
 
   error_t lookup_op (file_t startdir)
     {
-      while (file_name[0] == '/')
+      while (file_name[0] == '/' && file_name[1] == '/')
        file_name++;
 
       return lookup_error ((*lookup) (startdir, file_name, flags, mode,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]