Skip to content

Commit

Permalink
truename: fix array overrun (pick from fdpp)
Browse files Browse the repository at this point in the history
Picked from the commit at dosemu2/fdpp@fe1c4dc

The referenced issue is at dosemu2/fdpp#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 <[email protected]>
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.
  • Loading branch information
ecm-pushbx authored and PerditionC committed Aug 27, 2023
1 parent 29ccb6e commit 132a0a9
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions kernel/newstuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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; \
}

Expand Down Expand Up @@ -526,14 +529,18 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)

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 */
Expand All @@ -545,12 +552,9 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
}

/* 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 */
Expand Down Expand Up @@ -583,7 +587,7 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
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;
Expand All @@ -595,7 +599,7 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
state |= PNE_WILDCARD;
if (i) { /* name length in limits */
--i;
if (!DirChar(c)) PATH_ERROR;
if (!DirChar(c)) return PATH_ERROR();
addChar(c);
}
}
Expand Down

0 comments on commit 132a0a9

Please sign in to comment.