Re: sim/arm/armos.c: IsTTY [PATCH]

Shaun Jackman
2005-09-09T17:23:26Z

[-- Attachment #1: Type: text/plain, Size: 6391 bytes --]

2005/9/8, Richard Earnshaw <rearnsha@gcc.gnu.org>:
> Two problems I can immediately see with this.
>
> 1) PATH_MAX isn't ANSI (it's POSIX, or something like that). So you
> can't rely on it being defined. I think for this case you can probably
> just define it to 1024 anyway if it's missing, but see
> libiberty/lrealpath.c if you want the gory details.
>
> 2) If you do overflow the path limit, you need to set the simulator's
> errno value and return. Use cb_host_to_target_errno(sim_callback,
> ENAMETOOLONG) to set it.
>
> R.

I've changed PATH_MAX from POSIX to FILENAME_MAX from ANSI and checked
if the path limit overflowed.

Cheers,
Shaun

2005-09-09 Shaun Jackman <sjackman@gmail.com>

* sim/arm/armos.c (unlink): Remove this macro. It is unused
in this file and conflicts with sim_callback->unlink.
(SWIopen): Fix a potential buffer overflow.
(SWIremove): New function.
(SWIrename): Ditto.
(ARMul_OSHandleSWI): Handle the RDP calls SWI_IsTTY,
SWI_Remove, and SWI_Rename, as well as the RDI calls
AngelSWI_Reason_IsTTY, AngelSWI_Reason_Remove, and
AngelSWI_Reason_Rename.

Index: sim/arm/armos.c
===================================================================
RCS file: /cvs/src/src/sim/arm/armos.c,v
retrieving revision 1.22
diff -u -r1.22 armos.c
--- sim/arm/armos.c 12 May 2005 07:36:58 -0000 1.22
+++ sim/arm/armos.c 9 Sep 2005 17:19:08 -0000
@@ -27,6 +27,7 @@

#include <time.h>
#include <errno.h>
+#include <limits.h>
#include <string.h>
#include "targ-vals.h"

@@ -34,10 +35,6 @@
#define TARGET_O_BINARY 0
#endif

-#ifdef __STDC__
-#define unlink(s) remove(s)
-#endif
-
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* For SEEK_SET etc. */
#endif
@@ -303,18 +300,24 @@
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
{
struct OSblock *OSptr = (struct OSblock *) state->OSptr;
- char dummy[2000];
+ char buf[FILENAME_MAX], *p = buf;
int flags;
int i;

- for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
- ;
+ for (i = 0; i < sizeof buf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, name++)) == '\0')
+ break;
+ if (i == sizeof buf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }

/* Now we need to decode the Demon open mode. */
flags = translate_open_mode[SWIflags];

/* Filename ":tt" is special: it denotes stdin/out. */
- if (strcmp (dummy, ":tt") == 0)
+ if (strcmp (buf, ":tt") == 0)
{
if (flags == TARGET_O_RDONLY) /* opening tty "r" */
state->Reg[0] = 0; /* stdin */
@@ -323,7 +326,7 @@
}
else
{
- state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
+ state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}
}
@@ -403,6 +406,54 @@
OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

+static void
+SWIremove (ARMul_State * state, ARMword path)
+{
+ struct OSblock *OSptr = (struct OSblock *) state->OSptr;
+ char buf[FILENAME_MAX], *p = buf;
+ int i;
+
+ for (i = 0; i < sizeof buf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, path++)) == '\0')
+ break;
+ if (i == sizeof buf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+
+ state->Reg[0] = sim_callback->unlink (sim_callback, buf);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+}
+
+static void
+SWIrename (ARMul_State * state, ARMword old, ARMword new)
+{
+ struct OSblock *OSptr = (struct OSblock *) state->OSptr;
+ char oldbuf[FILENAME_MAX], newbuf[FILENAME_MAX], *p;
+ int i;
+
+ for (p = oldbuf, i = 0; i < sizeof oldbuf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, old++)) == '\0')
+ break;
+ if (i == sizeof oldbuf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+ for (p = newbuf, i = 0; i < sizeof newbuf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, new++)) == '\0')
+ break;
+ if (i == sizeof newbuf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+
+ state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+}
+
/* The emulator calls this routine when a SWI instruction is encuntered.
The parameter passed is the SWI number (lower 24 bits of the
instruction). */

@@ -544,6 +595,30 @@
state->Emulate = FALSE;
break;

+ case SWI_Remove:
+ if (swi_mask & SWI_MASK_DEMON)
+ SWIremove (state, state->Reg[0]);
+ else
+ unhandled = TRUE;
+ break;
+
+ case SWI_Rename:
+ if (swi_mask & SWI_MASK_DEMON)
+ SWIrename (state, state->Reg[0], state->Reg[1]);
+ else
+ unhandled = TRUE;
+ break;
+
+ case SWI_IsTTY:
+ if (swi_mask & SWI_MASK_DEMON)
+ {
+ state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+ }
+ else
+ unhandled = TRUE;
+ break;
+
/* Handle Angel SWIs as well as Demon ones. */
case AngelSWI_ARM:
case AngelSWI_Thumb:
@@ -566,10 +641,7 @@

/* Unimplemented reason codes. */
case AngelSWI_Reason_ReadC:
- case AngelSWI_Reason_IsTTY:
case AngelSWI_Reason_TmpNam:
- case AngelSWI_Reason_Remove:
- case AngelSWI_Reason_Rename:
case AngelSWI_Reason_System:
case AngelSWI_Reason_EnterSVC:
default:
@@ -684,6 +756,21 @@
ARMul_ReadWord (state, addr + 4),
ARMul_ReadWord (state, addr + 8));
break;
+
+ case AngelSWI_Reason_IsTTY:
+ state->Reg[0] = sim_callback->close (sim_callback,
+ ARMul_ReadWord (state, addr));
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+ break;
+
+ case AngelSWI_Reason_Remove:
+ SWIremove (state,
+ ARMul_ReadWord (state, addr));
+
+ case AngelSWI_Reason_Rename:
+ SWIrename (state,
+ ARMul_ReadWord (state, addr),
+ ARMul_ReadWord (state, addr + 4));
}
}
else

[-- Attachment #2: sim-arm-swi.diff --]
[-- Type: text/plain, Size: 5520 bytes --]

2005-09-09 Shaun Jackman <sjackman@gmail.com>

* sim/arm/armos.c (unlink): Remove this macro. It is unused
in this file and conflicts with sim_callback->unlink.
(SWIopen): Fix a potential buffer overflow.
(SWIremove): New function.
(SWIrename): Ditto.
(ARMul_OSHandleSWI): Handle the RDP calls SWI_IsTTY,
SWI_Remove, and SWI_Rename, as well as the RDI calls
AngelSWI_Reason_IsTTY, AngelSWI_Reason_Remove, and
AngelSWI_Reason_Rename.

Index: sim/arm/armos.c
===================================================================
RCS file: /cvs/src/src/sim/arm/armos.c,v
retrieving revision 1.22
diff -u -r1.22 armos.c
--- sim/arm/armos.c 12 May 2005 07:36:58 -0000 1.22
+++ sim/arm/armos.c 9 Sep 2005 17:19:08 -0000
@@ -27,6 +27,7 @@

#include <time.h>
#include <errno.h>
+#include <limits.h>
#include <string.h>
#include "targ-vals.h"

@@ -34,10 +35,6 @@
#define TARGET_O_BINARY 0
#endif

-#ifdef __STDC__
-#define unlink(s) remove(s)
-#endif
-
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* For SEEK_SET etc. */
#endif
@@ -303,18 +300,24 @@
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
{
struct OSblock *OSptr = (struct OSblock *) state->OSptr;
- char dummy[2000];
+ char buf[FILENAME_MAX], *p = buf;
int flags;
int i;

- for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
- ;
+ for (i = 0; i < sizeof buf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, name++)) == '\0')
+ break;
+ if (i == sizeof buf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }

/* Now we need to decode the Demon open mode. */
flags = translate_open_mode[SWIflags];

/* Filename ":tt" is special: it denotes stdin/out. */
- if (strcmp (dummy, ":tt") == 0)
+ if (strcmp (buf, ":tt") == 0)
{
if (flags == TARGET_O_RDONLY) /* opening tty "r" */
state->Reg[0] = 0; /* stdin */
@@ -323,7 +326,7 @@
}
else
{
- state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
+ state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}
}
@@ -403,6 +406,54 @@
OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
}

+static void
+SWIremove (ARMul_State * state, ARMword path)
+{
+ struct OSblock *OSptr = (struct OSblock *) state->OSptr;
+ char buf[FILENAME_MAX], *p = buf;
+ int i;
+
+ for (i = 0; i < sizeof buf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, path++)) == '\0')
+ break;
+ if (i == sizeof buf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+
+ state->Reg[0] = sim_callback->unlink (sim_callback, buf);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+}
+
+static void
+SWIrename (ARMul_State * state, ARMword old, ARMword new)
+{
+ struct OSblock *OSptr = (struct OSblock *) state->OSptr;
+ char oldbuf[FILENAME_MAX], newbuf[FILENAME_MAX], *p;
+ int i;
+
+ for (p = oldbuf, i = 0; i < sizeof oldbuf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, old++)) == '\0')
+ break;
+ if (i == sizeof oldbuf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+ for (p = newbuf, i = 0; i < sizeof newbuf; i++)
+ if ((*p++ = ARMul_SafeReadByte (state, new++)) == '\0')
+ break;
+ if (i == sizeof newbuf) {
+ state->Reg[0] = -1;
+ OSptr->ErrorNo = cb_host_to_target_errno(sim_callback, ENAMETOOLONG);
+ return;
+ }
+
+ state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+}
+
/* The emulator calls this routine when a SWI instruction is encuntered.
The parameter passed is the SWI number (lower 24 bits of the instruction). */

@@ -544,6 +595,30 @@
state->Emulate = FALSE;
break;

+ case SWI_Remove:
+ if (swi_mask & SWI_MASK_DEMON)
+ SWIremove (state, state->Reg[0]);
+ else
+ unhandled = TRUE;
+ break;
+
+ case SWI_Rename:
+ if (swi_mask & SWI_MASK_DEMON)
+ SWIrename (state, state->Reg[0], state->Reg[1]);
+ else
+ unhandled = TRUE;
+ break;
+
+ case SWI_IsTTY:
+ if (swi_mask & SWI_MASK_DEMON)
+ {
+ state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+ }
+ else
+ unhandled = TRUE;
+ break;
+
/* Handle Angel SWIs as well as Demon ones. */
case AngelSWI_ARM:
case AngelSWI_Thumb:
@@ -566,10 +641,7 @@

/* Unimplemented reason codes. */
case AngelSWI_Reason_ReadC:
- case AngelSWI_Reason_IsTTY:
case AngelSWI_Reason_TmpNam:
- case AngelSWI_Reason_Remove:
- case AngelSWI_Reason_Rename:
case AngelSWI_Reason_System:
case AngelSWI_Reason_EnterSVC:
default:
@@ -684,6 +756,21 @@
ARMul_ReadWord (state, addr + 4),
ARMul_ReadWord (state, addr + 8));
break;
+
+ case AngelSWI_Reason_IsTTY:
+ state->Reg[0] = sim_callback->close (sim_callback,
+ ARMul_ReadWord (state, addr));
+ OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
+ break;
+
+ case AngelSWI_Reason_Remove:
+ SWIremove (state,
+ ARMul_ReadWord (state, addr));
+
+ case AngelSWI_Reason_Rename:
+ SWIrename (state,
+ ARMul_ReadWord (state, addr),
+ ARMul_ReadWord (state, addr + 4));
}
}
else