Handle the conditional decoding of execve() argument and environment
arrays generically rather than duplicating a hack in all of the backends. - Add two new system call argument types and use them instead of StringArray for the argument and environment arguments execve and linux_execve. - Honor the -a/-e flags in the handling of these new types. - Instead of printing "<missing argument>" when the decoding is disabled, print the raw pointer value.
This commit is contained in:
parent
edef59ae52
commit
f335dbe91a
@ -233,28 +233,6 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,28 +233,6 @@ amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "freebsd32_execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "freebsd32_execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,28 +206,6 @@ amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "linux_execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,28 +264,6 @@ arm_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,28 +227,6 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,28 +206,6 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "linux_execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,28 +261,6 @@ mips_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,28 +238,6 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,28 +226,6 @@ powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,28 +255,6 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs)
|
|||||||
fprintf(trussinfo->outfile, "\n");
|
fprintf(trussinfo->outfile, "\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
|
|
||||||
strcmp(fsc->name, "exit") == 0)) {
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* This could be done in a more general
|
|
||||||
* manner but it still wouldn't be very pretty.
|
|
||||||
*/
|
|
||||||
if (strcmp(fsc->name, "execve") == 0) {
|
|
||||||
if ((trussinfo->flags & EXECVEARGS) == 0) {
|
|
||||||
if (fsc->s_args[1]) {
|
|
||||||
free(fsc->s_args[1]);
|
|
||||||
fsc->s_args[1] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((trussinfo->flags & EXECVEENVS) == 0) {
|
|
||||||
if (fsc->s_args[2]) {
|
|
||||||
free(fsc->s_args[2]);
|
|
||||||
fsc->s_args[2] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trussinfo->curthread->fsc = fsc;
|
trussinfo->curthread->fsc = fsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad,
|
|||||||
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
|
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
|
||||||
Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl,
|
Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl,
|
||||||
LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long,
|
LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long,
|
||||||
Sysarch };
|
Sysarch, ExecArgs, ExecEnv };
|
||||||
|
|
||||||
#define ARG_MASK 0xff
|
#define ARG_MASK 0xff
|
||||||
#define OUT 0x100
|
#define OUT 0x100
|
||||||
|
@ -245,11 +245,11 @@ static struct syscall syscalls[] = {
|
|||||||
.args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 },
|
.args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 },
|
||||||
{ Sockaddr | IN, 4 }, { Ptr | IN, 5 } } },
|
{ Sockaddr | IN, 4 }, { Ptr | IN, 5 } } },
|
||||||
{ .name = "execve", .ret_type = 1, .nargs = 3,
|
{ .name = "execve", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name | IN, 0 }, { StringArray | IN, 1 },
|
.args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
|
||||||
{ StringArray | IN, 2 } } },
|
{ ExecEnv | IN, 2 } } },
|
||||||
{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
|
{ .name = "linux_execve", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name | IN, 0 }, { StringArray | IN, 1 },
|
.args = { { Name | IN, 0 }, { ExecArgs | IN, 1 },
|
||||||
{ StringArray | IN, 2 } } },
|
{ ExecEnv | IN, 2 } } },
|
||||||
{ .name = "kldload", .ret_type = 0, .nargs = 1,
|
{ .name = "kldload", .ret_type = 0, .nargs = 1,
|
||||||
.args = { { Name | IN, 0 } } },
|
.args = { { Name | IN, 0 } } },
|
||||||
{ .name = "kldunload", .ret_type = 0, .nargs = 1,
|
{ .name = "kldunload", .ret_type = 0, .nargs = 1,
|
||||||
@ -912,6 +912,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ExecArgs:
|
||||||
|
case ExecEnv:
|
||||||
case StringArray: {
|
case StringArray: {
|
||||||
uintptr_t addr;
|
uintptr_t addr;
|
||||||
union {
|
union {
|
||||||
@ -922,6 +924,18 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
|
|||||||
size_t len;
|
size_t len;
|
||||||
int first, i;
|
int first, i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only parse argv[] and environment arrays from exec calls
|
||||||
|
* if requested.
|
||||||
|
*/
|
||||||
|
if (((sc->type & ARG_MASK) == ExecArgs &&
|
||||||
|
(trussinfo->flags & EXECVEARGS) == 0) ||
|
||||||
|
((sc->type & ARG_MASK) == ExecEnv &&
|
||||||
|
(trussinfo->flags & EXECVEENVS) == 0)) {
|
||||||
|
fprintf(fp, "0x%lx", args[sc->offset]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a page of pointers at a time. Punt if the top-level
|
* Read a page of pointers at a time. Punt if the top-level
|
||||||
* pointer is not aligned. Note that the first read is of
|
* pointer is not aligned. Note that the first read is of
|
||||||
|
Loading…
Reference in New Issue
Block a user