[smart] fixup of script execution (#9009)

This patch fixup the script execution capabilities on argv passing
and adds support for arguments larger than 4k.

According to POSIX, the script parameter is quiet different
from the current implementation. Especially on the way it inserts
the path of executables. At the end, when you execute a script
from `$PATH`, it always fails.

For the script, interpreter will be invoked with the following
arguments: `{interpreter [optional-arg] pathname arg...}`
where pathname is the pathname of the file specified as the first
argument of execve(), and arg...  is the series of words pointed
to by the argv argument of execve(), starting at argv[1].  Note that
there is no way to get the argv[0] that was passed to the
execve() call.

The changes include:

- Separating argument, environment variable, and auxiliary vector
  processing into a new lwp_args.c file.
- Fixing bugs in script argument processing and supporting arguments
  larger than 4k.
- Updating lwp_execve to use the new argscopy function and removing
  the old lwp_argscopy function.
- Making various modifications to lwp_load and elf_aux_fill to work
  with the new argument processing.
- Removing unnecessary code related to dynamic loading and interpreter
  scripts.

Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
Shell
2024-05-31 17:32:19 +08:00
committed by GitHub
parent 85b428df42
commit e5cf86267b
9 changed files with 940 additions and 1431 deletions
+29 -898
View File
File diff suppressed because it is too large Load Diff
+3 -9
View File
@@ -32,6 +32,7 @@
#include "lwp_signal.h"
#include "lwp_syscall.h"
#include "lwp_avl.h"
#include "lwp_args.h"
#include "mm_aspace.h"
#ifdef RT_USING_MUSLLIBC
@@ -237,6 +238,8 @@ void lwp_tid_dec_ref(rt_thread_t thread);
void lwp_tid_set_thread(int tid, rt_thread_t thread);
int lwp_execve(char *filename, int debug, int argc, char **argv, char **envp);
int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_t addr_size, struct process_aux *aux);
void lwp_user_obj_free(struct rt_lwp *lwp);
/*create by lwp_setsid.c*/
int setsid(void);
@@ -382,15 +385,6 @@ struct process_aux
struct process_aux_item item[AUX_ARRAY_ITEMS_NR];
};
struct lwp_args_info
{
char **argv;
char **envp;
int argc;
int envc;
int size;
};
struct dbg_ops_t
{
int (*dbg)(int argc, char **argv);
File diff suppressed because it is too large Load Diff
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-01-12 Shell separate argv, envp, aux processing from execve(2).
* Bugs fix for script arguments processing.
*/
#ifndef __LWP_ARGV_H__
#define __LWP_ARGV_H__
#include <rtthread.h>
struct rt_lwp;
enum lwp_args_type {
LWP_ARGS_TYPE_ARG,
LWP_ARGS_TYPE_KARG,
LWP_ARGS_TYPE_ENVP,
LWP_ARGS_TYPE_KENVP,
LWP_ARGS_TYPE_NULLPTR
};
struct lwp_string_vector
{
const char **strvec;
rt_uint32_t strvec_buflen;
rt_uint32_t string_count;
};
struct lwp_args_info
{
int argv0_strlen;
int strings_length;
int str_buf_size;
char *str_buf;
struct lwp_string_vector argv;
struct lwp_string_vector envp;
};
rt_err_t lwp_args_init(struct lwp_args_info *ai);
void lwp_args_detach(struct lwp_args_info *ai);
struct process_aux *lwp_argscopy(struct rt_lwp *lwp, struct lwp_args_info *args_info);;
rt_err_t lwp_args_put(struct lwp_args_info *args, const char **strv_addr, enum lwp_args_type atype);
rt_err_t lwp_args_put_argv(struct lwp_args_info *args, const char **argv_uaddr);
rt_err_t lwp_args_put_envp(struct lwp_args_info *args, const char **envp_uaddr);
rt_err_t lwp_args_load_script(struct lwp_args_info *args, const char *filename);
const char *lwp_args_get_argv_0(struct lwp_args_info *ai);
char** lwp_get_envp(struct rt_lwp *lwp, rt_size_t *penvp_counts);
void lwp_print_envp(struct rt_lwp *lwp);
char** lwp_get_command_line_args(struct rt_lwp *lwp);
void lwp_free_command_line_args(char** argv);
#endif /* __LWP_ARGV_H__ */
+11 -12
View File
@@ -47,11 +47,13 @@
#define ELF_EXEC_LOAD_ADDR USER_VADDR_START
#define ELF_INTERP_LOAD_ADDR LDSO_LOAD_VADDR
#define ELF_AUX_ENT(aux, id, val) \
do \
{ \
*aux++ = id; \
*aux++ = val; \
#define ELF_AUX_ENT(aux, id, val) \
do \
{ \
rt_base_t a = id; \
lwp_data_put(lwp, aux++, &a, sizeof(rt_ubase_t)); \
a = val; \
lwp_data_put(lwp, aux++, &a, sizeof(rt_ubase_t)); \
} while (0)
typedef struct
@@ -571,6 +573,7 @@ static int elf_aux_fill(elf_load_info_t *load_info)
uint32_t random_value = rt_tick_get();
size_t prot = PROT_READ | PROT_WRITE;
size_t flags = MAP_PRIVATE;
rt_lwp_t lwp = load_info->lwp;
void *va;
if (!aux)
@@ -581,7 +584,7 @@ static int elf_aux_fill(elf_load_info_t *load_info)
aux_info = (elf_addr_t *)aux->item;
ELF_AUX_ENT(aux_info, AT_PAGESZ, ARCH_PAGE_SIZE);
va = lwp_mmap2(load_info->lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE * 2), ARCH_PAGE_SIZE, prot, flags, -1, 0);
va = lwp_mmap2(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE * 2), ARCH_PAGE_SIZE, prot, flags, -1, 0);
if (!va)
{
LOG_E("lwp map user failed!");
@@ -604,10 +607,6 @@ static int elf_aux_fill(elf_load_info_t *load_info)
ELF_AUX_ENT(aux_info, AT_CLKTCK, 0);
ELF_AUX_ENT(aux_info, AT_SECURE, 0);
#ifdef ARCH_MM_MMU
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, aux, sizeof(*aux));
#endif
return 0;
}
@@ -757,7 +756,7 @@ OUT:
}
int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_t addr_size,
struct process_aux *aux)
struct process_aux *aux_ua)
{
elf_load_info_t load_info = { 0 };
int len;
@@ -789,7 +788,7 @@ int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_
}
load_info.lwp = lwp;
load_info.aux = aux;
load_info.aux = aux_ua;
load_info.exec_info.fd = ELF_INVALID_FD;
load_info.interp_info.fd = ELF_INVALID_FD;
-2
View File
@@ -186,6 +186,4 @@ rt_err_t lwp_critical_exit(struct rt_lwp *lwp);
#define LWP_RETURN(name) {RT_ASSERT(name != _LWP_UNINITIALIZED_RC);return name;}
#endif /* LWP_DEBUG */
int load_ldso(struct rt_lwp *lwp, char *exec_name, char *const argv[], char *const envp[]);
#endif /* __LWP_INTERNAL_H__ */
File diff suppressed because it is too large Load Diff
-67
View File
@@ -991,71 +991,4 @@ size_t lwp_strlen(struct rt_lwp *lwp, const char *s)
return strlen(s);
}
char** lwp_get_command_line_args(struct rt_lwp *lwp)
{
size_t argc = 0;
char** argv = NULL;
int ret;
size_t i;
size_t len;
if (lwp)
{
ret = lwp_data_get(lwp, &argc, lwp->args, sizeof(argc));
if (ret == 0)
{
return RT_NULL;
}
argv = (char**)rt_malloc((argc + 1) * sizeof(char*));
if (argv)
{
for (i = 0; i < argc; i++)
{
char *argvp = NULL;
ret = lwp_data_get(lwp, &argvp, &((char **)lwp->args)[1 + i], sizeof(argvp));
if (ret == 0)
{
lwp_free_command_line_args(argv);
return RT_NULL;
}
len = lwp_user_strlen_ext(lwp, argvp);
if (len > 0)
{
argv[i] = (char*)rt_malloc(len + 1);
ret = lwp_data_get(lwp, argv[i], argvp, len);
if (ret == 0)
{
lwp_free_command_line_args(argv);
return RT_NULL;
}
argv[i][len] = '\0';
}
else
{
argv[i] = NULL;
}
}
argv[argc] = NULL;
}
}
return argv;
}
void lwp_free_command_line_args(char** argv)
{
size_t i;
if (argv)
{
for (i = 0; argv[i]; i++)
{
rt_free(argv[i]);
}
rt_free(argv);
}
}
#endif
-3
View File
@@ -151,9 +151,6 @@ void lwp_unmap_user_space(struct rt_lwp *lwp);
int lwp_unmap_user(struct rt_lwp *lwp, void *va);
void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, rt_bool_t text);
void lwp_free_command_line_args(char** argv);
char** lwp_get_command_line_args(struct rt_lwp *lwp);
rt_varea_t lwp_map_user_varea(struct rt_lwp *lwp, void *map_va, size_t map_size);
/* check LWP_MAP_FLAG_* */