This MR main goal is to fix buffer overflow in MKLINK commands. Also added some more syntax error detections cases.
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 7d1ad5c1e15..4828533e5e5 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -4051,13 +4051,13 @@ RETURN_CODE WCMD_mklink(WCHAR *args) BOOL isdir = FALSE; BOOL junction = FALSE; BOOL hard = FALSE; - BOOL ret = FALSE; + BOOL ret = TRUE; WCHAR file1[MAX_PATH]; WCHAR file2[MAX_PATH];
file1[0] = file2[0] = L'\0';
- while (argN) { + while (argN && ret) { WCHAR *thisArg = WCMD_parameter (args, argno++, &argN, FALSE, FALSE);
if (!argN) break; @@ -4071,28 +4071,31 @@ RETURN_CODE WCMD_mklink(WCHAR *args) else if (lstrcmpiW(thisArg, L"/J") == 0) junction = TRUE; else if (*thisArg == L'/') - { - return errorlevel = ERROR_INVALID_FUNCTION; - } + ret = FALSE; else { - if(!file1[0]) + if (!file1[0]) lstrcpyW(file1, thisArg); - else + else if (!file2[0]) lstrcpyW(file2, thisArg); + else + ret = FALSE; } }
- if (*file1 && *file2) + if (!file2[0] || !ret) { - if (hard) - ret = CreateHardLinkW(file1, file2, NULL); - else if(!junction) - ret = CreateSymbolicLinkW(file1, file2, isdir); - else - ret = create_mount_point(file1, file2); + WCMD_output_stderr(WCMD_LoadMessage(WCMD_SYNTAXERR)); + return errorlevel = ERROR_INVALID_FUNCTION; }
+ if (hard) + ret = CreateHardLinkW(file1, file2, NULL); + else if (!junction) + ret = CreateSymbolicLinkW(file1, file2, isdir); + else + ret = create_mount_point(file1, file2); + if (ret) return errorlevel = NO_ERROR;
WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), file1);
From: Eric Pouech epouech@codeweavers.com
Also ensuring that all paths created with MKLINK fit within the MAX_PATH limit.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 4828533e5e5..d9267d84412 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -3967,10 +3967,10 @@ RETURN_CODE WCMD_color(void)
/* We cannot use SetVolumeMountPoint(), because that function forbids setting * arbitrary directories as mount points, whereas mklink /j allows it. */ -BOOL create_mount_point(const WCHAR *link, const WCHAR *target) { +BOOL create_mount_point(const WCHAR *full_link, const WCHAR *target) { char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER *data = (void *)buffer; - WCHAR full_link[MAX_PATH], *full_target; + WCHAR *full_target; UNICODE_STRING nt_link, nt_target; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; @@ -3979,10 +3979,7 @@ BOOL create_mount_point(const WCHAR *link, const WCHAR *target) { DWORD size; BOOL ret;
- TRACE( "link %s, target %s\n", debugstr_w(link), debugstr_w(target) ); - - if (!WCMD_get_fullpath(link, ARRAY_SIZE(full_link), full_link, NULL)) - return FALSE; + TRACE( "link %s, target %s\n", debugstr_w(full_link), debugstr_w(target) );
if (!(size = GetFullPathNameW(target, 0, NULL, NULL))) return FALSE; @@ -4053,7 +4050,7 @@ RETURN_CODE WCMD_mklink(WCHAR *args) BOOL hard = FALSE; BOOL ret = TRUE; WCHAR file1[MAX_PATH]; - WCHAR file2[MAX_PATH]; + WCHAR file2[MAXSTRING];
file1[0] = file2[0] = L'\0';
@@ -4075,9 +4072,9 @@ RETURN_CODE WCMD_mklink(WCHAR *args) else { if (!file1[0]) - lstrcpyW(file1, thisArg); + ret = WCMD_get_fullpath(thisArg, ARRAY_SIZE(file1), file1, NULL); else if (!file2[0]) - lstrcpyW(file2, thisArg); + wcscpy(file2, thisArg); else ret = FALSE; }