[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,
- [PATCH] fix the trailing slash issue in dir_lookup calls,
Flavio Cruz <=