From 9c58150f11d320ebcc131933251d25cde01968b2 Mon Sep 17 00:00:00 2001
From: Felip Moll <felip.moll@schedmd.com>
Date: Tue, 17 Jul 2018 00:44:10 +0200
Subject: [PATCH] Improve escaping paths on user commands

When dealing with special characters like %A, %u, %s and so on and escaping it
on the command line, problems arises when one have directories with multiple
slashes in their names. This patch fixes this situation removing only one
slash on each pair of slashes just as normal escaping works i.e. in bash.

Bug 4859
---
 NEWS                      |  1 +
 src/slurmd/common/fname.c | 28 +++++++++++++++++++---------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/NEWS b/NEWS
index 3d76e4e24e5..41d9380e6d1 100644
--- a/NEWS
+++ b/NEWS
@@ -82,6 +82,7 @@ documents those changes that are of interest to users and administrators.
  -- Fix issue in performance when reading slurm conf having nodes with features.
  -- Make it so the slurmdbd's pid file gets created before initing
     the database.
+ -- Improve escaping special characters on user commands when specifying paths.
 
 * Changes in Slurm 18.08.0pre1
 ==============================
diff --git a/src/slurmd/common/fname.c b/src/slurmd/common/fname.c
index d84fd153151..50eacab13f4 100644
--- a/src/slurmd/common/fname.c
+++ b/src/slurmd/common/fname.c
@@ -387,13 +387,12 @@ extern int fname_single_task_io (const char *fmt)
 
 /* is_path_escaped()
  *
- * If there are \ chars in the path strip them.
- * The new path will tell the caller not to
- * translate escaped characters.
+ * If there are \ chars in the path strip the escaping ones.
+ * The new path will tell the caller not to translate escaped characters.
  */
 extern char *is_path_escaped(char *p)
 {
-	char *buf;
+	char *buf, *pp;
 	bool t;
 	int i;
 
@@ -404,20 +403,31 @@ extern char *is_path_escaped(char *p)
 	t = false;
 	i = 0;
 
+	pp = p;
+	++pp;
 	while (*p) {
-		if (*p == '\\') {
+		if (*p == '\\' && *pp == '\\') {
 			t = true;
+			buf[i] = *pp;
+			++i;
+			p = p + 2;
+			pp = pp + 2;
+		} else if (*p == '\\') {
+			t = true;
+			++p;
+			++pp;
+		} else {
+			buf[i] = *p;
+			++i;
 			++p;
-			continue;
+			++pp;
 		}
-		buf[i] = *p;
-		++i;
-		++p;
 	}
 
 	if (t == false) {
 		xfree(buf);
 		return NULL;
 	}
+
 	return buf;
 }
-- 
GitLab