From 0dc1bfb7302d220a48364263d5632d6d572b069b Mon Sep 17 00:00:00 2001
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
Date: Mon, 2 Jul 2018 02:41:23 +0200
Subject: [PATCH] fs: fat: cannot write to subdirectories

fs_fat_write() is not able to write to subdirectories.

Currently if a filepath with a leading slash is passed, the slash is
treated as part of the filename to be created in the root directory.

Strip leading (back-)slashes.

Check that the remaining filename does not contain any illegal characters
(<>:"/\|?*). This way we will throw an error when trying to write to a
subdirectory.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 fs/fat/fat_write.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 3b77557b3e..27e0ff6696 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -909,9 +909,11 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
 	volume_info volinfo;
 	fsdata datablock;
 	fsdata *mydata = &datablock;
-	int cursect;
+	int cursect, i;
 	int ret = -1, name_len;
 	char l_filename[VFAT_MAXLEN_BYTES];
+	char bad[2] = " ";
+	const char illegal[] = "<>:\"/\\|?*";
 
 	*actwrite = size;
 	dir_curclust = 0;
@@ -971,6 +973,18 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
 	}
 	dentptr = (dir_entry *) do_fat_read_at_block;
 
+	/* Strip leading (back-)slashes */
+	while ISDIRDELIM(*filename)
+		++filename;
+	/* Check that the filename is valid */
+	for (i = 0; i < strlen(illegal); ++i) {
+		*bad = illegal[i];
+		if (strstr(filename, bad)) {
+			printf("FAT: illegal filename (%s)\n", filename);
+			return -1;
+		}
+	}
+
 	name_len = strlen(filename);
 	if (name_len >= VFAT_MAXLEN_BYTES)
 		name_len = VFAT_MAXLEN_BYTES - 1;
-- 
2.39.5