Add support for syscall with more than 3 args

This commit is contained in:
Mathieu Maret 2021-11-08 23:22:03 +01:00
parent 444bc6a5e9
commit e9e584149c
8 changed files with 107 additions and 7 deletions

View File

@ -10,6 +10,7 @@
#include "gdt.h"
#include "klibc.h"
#include "segment.h"
#include "uaccess.h"
/**
* Here is the definition of a CPU context for IA32 processors. This
@ -512,7 +513,7 @@ int syscallGet1arg(const struct cpu_state *user_ctxt,
}
int _syscallGet2args(const struct cpu_state *user_ctxt,
int syscallGet2args(const struct cpu_state *user_ctxt,
/* out */unsigned int *arg1,
/* out */unsigned int *arg2)
{
@ -520,3 +521,52 @@ int _syscallGet2args(const struct cpu_state *user_ctxt,
return syscallGet3args(user_ctxt, arg1, arg2, & unused);
}
int syscallGet4args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3,
/* out */ unsigned int *arg4)
{
uaddr_t userOtherArgs;
unsigned int otherArgs[2];
int ret;
ret = syscallGet3args(user_ctxt, arg1, arg2, (unsigned int *)&userOtherArgs);
if (ret)
return ret;
ret = memcpyFromUser((vaddr_t)otherArgs, userOtherArgs, sizeof(otherArgs));
if (ret != sizeof(otherArgs))
return -EFAULT;
*arg3 = otherArgs[0];
*arg4 = otherArgs[1];
return 0;
}
int syscallGet5args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3,
/* out */ unsigned int *arg4,
/* out */ unsigned int *arg5)
{
uaddr_t userOtherArgs;
unsigned int otherArgs[3];
int ret;
ret = syscallGet3args(user_ctxt, arg1, arg2, (unsigned int *)&userOtherArgs);
if (ret)
return ret;
ret = memcpyFromUser((vaddr_t)otherArgs, userOtherArgs, sizeof(otherArgs));
if (ret != sizeof(otherArgs))
return -EFAULT;
*arg3 = otherArgs[0];
*arg4 = otherArgs[1];
*arg5 = otherArgs[2];
return 0;
}

View File

@ -204,14 +204,27 @@ void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt,
int cpu_ustate_init(struct cpu_state **ctx, uaddr_t startPC, uint32_t arg1, uint32_t arg2,
uaddr_t startSP, vaddr_t kernelStackBottom, size_t kernelStackSize);
int syscallGet3args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3);
int syscallGet1arg(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1);
int syscallGet2args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2);
int syscallGet3args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3);
int syscallGet4args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3,
/* out */ unsigned int *arg4);
int syscallGet5args(const struct cpu_state *user_ctxt,
/* out */ unsigned int *arg1,
/* out */ unsigned int *arg2,
/* out */ unsigned int *arg3,
/* out */ unsigned int *arg4,
/* out */ unsigned int *arg5);

View File

@ -7,7 +7,7 @@
int syscallExecute(int syscallId, const struct cpu_state *userCtx)
{
int ret;
int ret = 0;
switch (syscallId) {
case SYSCALL_ID_EXIT: {
@ -31,6 +31,12 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
case SYSCALL_ID_READ:
ret = keyboardRead();
break;
case SYSCALL_ID_TEST: {
unsigned int arg1, arg2, arg3, arg4, arg5;
ret = syscallGet5args(userCtx, &arg1, &arg2, &arg3, &arg4, &arg5);
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
break;
}
default:
printf("Unknon syscall id %d\n", syscallId);
ret = -ENOENT;

View File

@ -7,6 +7,7 @@
#define SYSCALL_ID_YOLO 2
#define SYSCALL_ID_PUTC 3
#define SYSCALL_ID_READ 4
#define SYSCALL_ID_TEST 5
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -7,6 +7,7 @@
#define SYSCALL_ID_YOLO 2
#define SYSCALL_ID_PUTC 3
#define SYSCALL_ID_READ 4
#define SYSCALL_ID_TEST 5
#ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -467,6 +467,20 @@ int vasprintf(char **strp, const char *fmt, va_list ap)
return size;
}
int syscall5(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3,
unsigned int arg4, unsigned int arg5)
{
unsigned int args[] = {arg3, arg4, arg5};
return syscall3(id, arg1, arg2, (unsigned)args);
}
int syscall4(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3,
unsigned int arg4)
{
unsigned int args[] = {arg3, arg4};
return syscall3(id, arg1, arg2, (unsigned)args);
}
int syscall3(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3)
{
int ret;
@ -513,6 +527,11 @@ void yolo()
syscall0(SYSCALL_ID_YOLO);
}
int testSycall5(uint arg1, uint arg2, uint arg3, uint arg4, uint arg5)
{
return syscall5(SYSCALL_ID_TEST, arg1, arg2, arg3, arg4, arg5);
}
char readc()
{
return syscall0(SYSCALL_ID_READ);

View File

@ -30,6 +30,10 @@ int printf(const char *format, ...);
int asprintf(char **strp, const char *fmt, ...);
int vasprintf(char **strp, const char *fmt, va_list ap);
int syscall5(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3,
unsigned int arg4, unsigned int arg5);
int syscall4(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3,
unsigned int arg4);
int syscall3(int id, unsigned int arg1, unsigned int arg2, unsigned int arg3);
int syscall2(int id, unsigned int arg1, unsigned int arg2);
int syscall1(int id, unsigned int arg1);
@ -37,6 +41,7 @@ int syscall0(int id);
void _exit(int status);
void yolo();
int testSycall5(uint arg1, uint arg2, uint arg3, uint arg4, uint arg5);
char readc();
char readcBlock();
int readline(char *buf, int size);

View File

@ -12,6 +12,7 @@ int func_help()
printf(" yolo\n");
printf(" suicide\n");
printf(" help\n");
printf(" syscall5\n");
return 0;
}
@ -45,6 +46,10 @@ int main(int argc, char *argv[])
func_suicide();
continue;
}
if (strcmp(buf, "syscall5") == 0) {
testSycall5(1, 2, 3, 4, 5);
continue;
}
}
return 0;
}