From 132a0a9f94d23f13c90319bb0e0232a5f33164d8 Mon Sep 17 00:00:00 2001 From: "C. Masloch" Date: Sat, 26 Aug 2023 22:22:30 +0200 Subject: [PATCH] truename: fix array overrun (pick from fdpp) Picked from the commit at https://github.com/dosemu2/fdpp/commit/fe1c4dc7fe5a2218d3badf90c3a8e43550da5821 The referenced issue is at https://github.com/dosemu2/fdpp/issues/212 The patch was applied using unix2dos on the patch file then `patch -p1 --binary` with the patch file as stdin. The original used a new define for the maximum path length. As there is no difference to our current SFTMAX define I changed this hunk to retain the SFTMAX use. This fixes a bug when eg function 3Dh receives a buffer that starts with ".\" but the byte in memory before this buffer happens to be also a dot. I ran into this problem semi-randomly during building EDR-DOS with the most recent WarpLink build. If WarpLink was placed somewhat low in the Low Memory Area then one of its function 3Dh calls would happen to have a dot before the pathname buffer. (I had to load lCDebug using the last fit strategy then enter TSR mode, to catch the bug without the presence of the debugger working around the occurrence of the bug.) Original commit Metadata: From: Stas Sergeev Date: Wed, 1 Feb 2023 13:01:55 +0500 Subject: [PATCH] truename: fix array overrun [fixes #212] src[-2] was peeking into a random memory location. It seems entire truename() is written by some morons... :( Its completely unreadable and full of bugs. --- kernel/newstuff.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/kernel/newstuff.c b/kernel/newstuff.c index 9fbe142..9fe7347 100644 --- a/kernel/newstuff.c +++ b/kernel/newstuff.c @@ -185,7 +185,10 @@ long DosMkTmp(BYTE FAR * pathname, UWORD attr) */ -#define PATH_ERROR goto errRet +#define PATH_ERROR() \ + fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0 \ + ? DE_FILENOTFND \ + : DE_PATHNOTFND #define PATHLEN 128 @@ -249,7 +252,7 @@ STATIC const char _DirChars[] = "\"[]:|<>+=;,"; #define addChar(c) \ { \ - if (p >= dest + SFTMAX) PATH_ERROR; /* path too long */ \ + if (p >= dest + SFTMAX) return PATH_ERROR(); /* path too long */ \ *p++ = c; \ } @@ -526,14 +529,18 @@ invalid_path: if(*src == '.') { + int dots = 1; /* special directory component */ ++src; if (*src == '.') /* skip the second dot */ + { ++src; + dots++; + } if (*src == '/' || *src == '\\' || *src == '\0') { --p; /* backup the backslash */ - if (src[-2] == '.') + if (dots == 2) { /* ".." entry */ /* remove last path component */ @@ -545,12 +552,9 @@ invalid_path: } /* ill-formed .* or ..* entries => return error */ - errRet: /* The error is either PATHNOTFND or FILENOTFND depending on if it is not the last component */ - return fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0 - ? DE_FILENOTFND - : DE_PATHNOTFND; + return PATH_ERROR(); } /* normal component */ @@ -583,7 +587,7 @@ invalid_path: if (c == '.') { if (state & PNE_DOT) /* multiple dots are ill-formed */ - PATH_ERROR; + return PATH_ERROR(); /* strip trailing dot */ if (*src == '/' || *src == '\\' || *src == '\0') break; @@ -595,7 +599,7 @@ invalid_path: state |= PNE_WILDCARD; if (i) { /* name length in limits */ --i; - if (!DirChar(c)) PATH_ERROR; + if (!DirChar(c)) return PATH_ERROR(); addChar(c); } }