summaryrefslogtreecommitdiff
path: root/exec
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2026-05-25 11:21:00 +0800
committerPo Lu <luangruo@yahoo.com>2026-05-25 11:21:00 +0800
commit44013f6be751363f7c4c642ebbfd618110db8b75 (patch)
tree413cdaa5395d719e3466c979d969587e348a4d43 /exec
parentb72dcebdabfc3b7b28c9542633bd48b43bcc6365 (diff)
Revert "Don’t silently truncate file names in exec.c"
This reverts commit 3461b450c5eae3ed53192aa9514e0b1ac1b1c8f2. Gnulib and intprops.h are not available from within the exec helper.
Diffstat (limited to 'exec')
-rw-r--r--exec/exec.c96
-rw-r--r--exec/trace.c2
2 files changed, 49 insertions, 49 deletions
diff --git a/exec/exec.c b/exec/exec.c
index ace62dd0191..7736c0dab27 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -863,25 +863,32 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
-/* Format PID, a nonnegative process identifier, in base 10.
- Place the result in *IN. Do not null-terminate the result.
- Possibly modify the bytes in IN that are after the result.
- Return a pointer to the byte after the result. */
+/* Format PID, an unsigned process identifier, in base 10. Place the
+ result in *IN, and return a pointer to the byte after the
+ result. REM should be NULL. */
char *
-format_pid (char in[INT_STRLEN_BOUND (pid_t)], pid_t pid)
+format_pid (char *in, unsigned int pid)
{
- char *pend = in + INT_STRLEN_BOUND (pid_t);
- char *p = pend;
+ unsigned int digits[32], *fill;
- do
- *--p = '0' + pid % 10;
- while ((pid /= 10) != 0);
+ fill = digits;
- do
- *in++ = *p++;
- while (p < pend);
+ for (; pid != 0; pid = pid / 10)
+ *fill++ = pid % 10;
+
+ /* Insert 0 if the number would otherwise be empty. */
+
+ if (fill == digits)
+ *fill++ = 0;
+
+ while (fill != digits)
+ {
+ --fill;
+ *in++ = '0' + *fill;
+ }
+ *in = '\0';
return in;
}
@@ -897,13 +904,10 @@ format_pid (char in[INT_STRLEN_BOUND (pid_t)], pid_t pid)
Finally, use REGS to add the required interpreter arguments to the
caller's argv.
- NAME must be a null-terminated string in a buffer of size PATH_MAX.
- It might be updated to be a string no longer than PATH_MAX - 1.
-
Value is NULL upon failure, with errno set accordingly. */
char *
-exec_0 (char name[PATH_MAX], struct exec_tracee *tracee,
+exec_0 (char *name, struct exec_tracee *tracee,
size_t *size, USER_REGS_STRUCT *regs)
{
int fd, rc, i;
@@ -912,13 +916,14 @@ exec_0 (char name[PATH_MAX], struct exec_tracee *tracee,
program_header program;
USER_WORD entry, program_entry, offset;
USER_WORD header_offset;
- ptrdiff_t nlen;
USER_WORD name_len, aligned_len;
struct exec_jump_command jump;
/* This also encompasses !__LP64__. */
#if defined __mips__ && !defined MIPS_NABI
int fpu_mode;
#endif /* defined __mips__ && !defined MIPS_NABI */
+ char buffer[80], buffer1[PATH_MAX + 80], *rewrite;
+ ssize_t link_size;
size_t remaining;
/* If the process is trying to run /proc/self/exe, make it run
@@ -926,13 +931,8 @@ exec_0 (char name[PATH_MAX], struct exec_tracee *tracee,
if (!strcmp (name, "/proc/self/exe") && tracee->exec_file)
{
- nlen = strnlen (tracee->exec_file, PATH_MAX);
- if (PATH_MAX <= nlen)
- {
- errno = ENAMETOOLONG;
- return NULL;
- }
- memcpy (name, tracee->exec_file, nlen + 1);
+ strncpy (name, tracee->exec_file, PATH_MAX - 1);
+ name[PATH_MAX] = '\0';
}
else
{
@@ -940,45 +940,45 @@ exec_0 (char name[PATH_MAX], struct exec_tracee *tracee,
cwd. Do not use sprintf at it is not reentrant and it
mishandles results longer than INT_MAX. */
- nlen = strlen (name);
-
if (name[0] && name[0] != '/')
{
- char buffer[sizeof "/proc//cwd" + INT_STRLEN_BOUND (pid_t)];
- char buffer1[PATH_MAX];
+ /* Clear both buffers. */
+ memset (buffer, 0, sizeof buffer);
+ memset (buffer1, 0, sizeof buffer1);
- /* Copy over "/proc/", the PID, and "/cwd". */
- char *rewrite = stpcpy (buffer, "/proc/");
+ /* Copy over /proc, the PID, and /cwd/. */
+ rewrite = stpcpy (buffer, "/proc/");
rewrite = format_pid (rewrite, tracee->pid);
strcpy (rewrite, "/cwd");
/* Resolve this symbolic link. */
- ssize_t link_size = readlink (buffer, buffer1, sizeof buffer1);
+ link_size = readlink (buffer, buffer1,
+ PATH_MAX + 1);
+
if (link_size < 0)
return NULL;
- /* Check that the link is reasonable. */
+ /* Check that the name is a reasonable size. */
- if (link_size == 0 || buffer1[0] != '/')
- {
- errno = EINVAL;
- return NULL;
- }
-
- ptrdiff_t link_len = link_size - (buffer1[link_size - 1] == '/');
- if (PATH_MAX <= link_len + 1 + nlen)
+ if (link_size > PATH_MAX)
{
+ /* The name is too long. */
errno = ENAMETOOLONG;
return NULL;
}
- /* Replace name with link contents,
- then '/' if needed, then name. */
- memmove (name + link_len + 1, name, nlen + 1);
- memcpy (name, buffer1, link_len);
- name[link_len] = '/';
- nlen += link_len + 1;
+ /* Add a directory separator if necessary. */
+
+ if (!link_size || buffer1[link_size - 1] != '/')
+ buffer1[link_size] = '/', link_size++;
+
+ rewrite = buffer1 + link_size;
+ remaining = buffer1 + sizeof buffer1 - rewrite - 1;
+ memcpy (rewrite, name, strnlen (name, remaining));
+
+ /* Replace name with buffer1. */
+ strcpy (name, buffer1);
}
}
@@ -1151,7 +1151,7 @@ exec_0 (char name[PATH_MAX], struct exec_tracee *tracee,
loader_area_used += sizeof jump;
/* Copy the length of NAME and NAME itself to the loader area. */
- name_len = nlen;
+ name_len = strlen (name);
aligned_len = ((name_len + 1 + sizeof name_len - 1)
& -sizeof name_len);
if (sizeof loader_area - loader_area_used
diff --git a/exec/trace.c b/exec/trace.c
index d3d6f223eb8..da9ac96c6ff 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -732,7 +732,7 @@ check_signal (struct exec_tracee *tracee, int status)
static int
handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
{
- char buffer[PATH_MAX], *area;
+ char buffer[PATH_MAX + 80], *area;
USER_REGS_STRUCT original;
size_t size, loader_size;
USER_WORD loader;