Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscalls: Sanitize all pointers #606

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 113 additions & 21 deletions syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@

void syscalls_debug(void *ustack)
{
process_t *proc = proc_current()->process;
const char *s;

/* FIXME: pass strlen(s) from userspace */

GETFROMSTACK(ustack, const char *, s, 0);
hal_consolePrint(ATTR_USER, s);

if (vm_mapStringBelongs(proc, s) == 0) {
hal_consolePrint(ATTR_USER, s);
}
}


Expand Down Expand Up @@ -173,52 +175,119 @@ int syscalls_release(void *ustack)
}


static int syscalls_sanitizeVector(process_t *proc, char **v)
{
size_t i;

if (v == NULL) {
return 0;
}

if (vm_mapBelongs(proc, v, sizeof(v)) < 0) {
return -1;
}

for (i = 0;; ++i) {
if (vm_mapBelongs(proc, &v[i], sizeof(v)) < 0) {
return -1;
}

if (v[i] == NULL) {
break;
}

if (vm_mapStringBelongs(proc, v[i]) < 0) {
return -1;
}
}

return 0;
}


int syscalls_sys_spawn(void *ustack)
{
process_t *proc = proc_current()->process;
char *path;
char **argv;
char **envp;

/* FIXME pass fields lengths from userspace */

GETFROMSTACK(ustack, char *, path, 0);
GETFROMSTACK(ustack, char **, argv, 1);
GETFROMSTACK(ustack, char **, envp, 2);

if (vm_mapStringBelongs(proc, path) < 0) {
return -EFAULT;
}

if (syscalls_sanitizeVector(proc, argv) < 0) {
return -EFAULT;
}

if (syscalls_sanitizeVector(proc, envp) < 0) {
return -EFAULT;
}

return proc_fileSpawn(path, argv, envp);
}


int syscalls_exec(void *ustack)
{
process_t *proc = proc_current()->process;
char *path;
char **argv;
char **envp;

/* FIXME pass fields lengths from userspace */

GETFROMSTACK(ustack, char *, path, 0);
GETFROMSTACK(ustack, char **, argv, 1);
GETFROMSTACK(ustack, char **, envp, 2);

if (vm_mapStringBelongs(proc, path) < 0) {
return -EFAULT;
}

if (syscalls_sanitizeVector(proc, argv) < 0) {
return -EFAULT;
}

if (syscalls_sanitizeVector(proc, envp) < 0) {
return -EFAULT;
}

return proc_execve(path, argv, envp);
}


int syscalls_spawnSyspage(void *ustack)
{
process_t *proc = proc_current()->process;
char *imap;
char *dmap;
char *name;
char **argv;

/* FIXME pass fields lengths from userspace */

GETFROMSTACK(ustack, char *, imap, 0);
GETFROMSTACK(ustack, char *, dmap, 1);
GETFROMSTACK(ustack, char *, name, 2);
GETFROMSTACK(ustack, char **, argv, 3);

if (vm_mapStringBelongs(proc, imap) < 0) {
return -EFAULT;
}

if (vm_mapStringBelongs(proc, dmap) < 0) {
return -EFAULT;
}

if (vm_mapStringBelongs(proc, name) < 0) {
return -EFAULT;
}

if (syscalls_sanitizeVector(proc, argv) < 0) {
return -EFAULT;
}

return proc_syspageSpawnName(imap, dmap, name, argv);
}

Expand Down Expand Up @@ -729,7 +798,9 @@ u32 syscalls_portRegister(void *ustack)
GETFROMSTACK(ustack, char *, name, 1);
GETFROMSTACK(ustack, oid_t *, oid, 2);

/* FIXME: Pass strlen(name) from userspace */
if (vm_mapStringBelongs(proc, name) < 0) {
return -EFAULT;
}

if (vm_mapBelongs(proc, oid, sizeof(*oid)) < 0) {
return -EFAULT;
Expand Down Expand Up @@ -828,7 +899,9 @@ int syscalls_lookup(void *ustack)
GETFROMSTACK(ustack, oid_t *, file, 1);
GETFROMSTACK(ustack, oid_t *, dev, 2);

/* FIXME: Pass strlen(name) from userspace */
if (vm_mapStringBelongs(proc, name) < 0) {
return -EFAULT;
}

if ((file != NULL) && (vm_mapBelongs(proc, file, sizeof(*file)) < 0)) {
return -EFAULT;
Expand Down Expand Up @@ -1066,14 +1139,17 @@ void syscalls_sigreturn(void *ustack)

int syscalls_sys_open(char *ustack)
{
process_t *proc = proc_current()->process;
const char *filename;
int oflag;

/* FIXME: pass strlen(filename) from userspace */

GETFROMSTACK(ustack, const char *, filename, 0);
GETFROMSTACK(ustack, int, oflag, 1);

if (vm_mapStringBelongs(proc, filename) < 0) {
return -EFAULT;
}

return posix_open(filename, oflag, ustack);
}

Expand Down Expand Up @@ -1158,26 +1234,36 @@ int syscalls_sys_dup2(char *ustack)

int syscalls_sys_link(char *ustack)
{
process_t *proc = proc_current()->process;
const char *path1;
const char *path2;

/* FIXME pass strlen(path1) and strlen(path2) from userspace */

GETFROMSTACK(ustack, const char *, path1, 0);
GETFROMSTACK(ustack, const char *, path2, 1);

if (vm_mapStringBelongs(proc, path1) < 0) {
return -EFAULT;
}

if (vm_mapStringBelongs(proc, path2) < 0) {
return -EFAULT;
}

return posix_link(path1, path2);
}


int syscalls_sys_unlink(char *ustack)
{
process_t *proc = proc_current()->process;
const char *pathname;

/* FIXME: pass strlen(pathname) from userspace */

GETFROMSTACK(ustack, const char *, pathname, 0);

if (vm_mapStringBelongs(proc, pathname) < 0) {
return -EFAULT;
}

return posix_unlink(pathname);
}

Expand Down Expand Up @@ -1242,14 +1328,17 @@ int syscalls_sys_pipe(char *ustack)

int syscalls_sys_mkfifo(char *ustack)
{
process_t *proc = proc_current()->process;
const char *path;
mode_t mode;

/* FIXME: pass strlen(path) from userspace */

GETFROMSTACK(ustack, const char *, path, 0);
GETFROMSTACK(ustack, mode_t, mode, 1);

if (vm_mapStringBelongs(proc, path) < 0) {
return -EFAULT;
}

return posix_mkfifo(path, mode);
}

Expand Down Expand Up @@ -1283,14 +1372,17 @@ int syscalls_sys_fsync(char *ustack)

int syscalls_sys_chmod(char *ustack)
{
process_t *proc = proc_current()->process;
const char *path;
mode_t mode;

/* FIXME: pass strlen(path) from userspace */

GETFROMSTACK(ustack, const char *, path, 0);
GETFROMSTACK(ustack, mode_t, mode, 1);

if (vm_mapStringBelongs(proc, path) < 0) {
return -EFAULT;
}

return posix_chmod(path, mode);
}

Expand Down
27 changes: 27 additions & 0 deletions vm/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,33 @@
}


int vm_mapStringBelongs(const struct _process_t *proc, const char *str)
{
int ret;

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a7-imx6ull-evk)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a9-zynq7000-qemu)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a9-zynq7000-zedboard)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7a9-zynq7000-zturn)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m4-stm32l4x6-nucleo)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt105x-evk)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt106x-evk)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt117x-evk)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv8r52-mps3an536-qemu)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv8m33-mcxn94x-frdm)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (ia32-generic-pc)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (ia32-generic-qemu)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (riscv64-generic-qemu)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (riscv64-generic-spike)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (sparcv8leon3-gr712rc-board)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (sparcv8leon3-gr716-mimas)

unused variable 'ret' [-Wunused-variable]

Check warning on line 1125 in vm/map.c

View workflow job for this annotation

GitHub Actions / call-ci / build (sparcv8leon3-gr716-mini)

unused variable 'ret' [-Wunused-variable]
const char *page = (const char *)((ptr_t)str & (SIZE_PAGE - 1));
size_t offs = (ptr_t)str - (ptr_t)page;

proc_lockSet(&proc->mapp->lock);

while (_vm_mapBelongs(proc, page, SIZE_PAGE) == 0) {
while (offs < SIZE_PAGE) {
if (page[offs] == '\0') {
proc_lockClear(&proc->mapp->lock);
return 0;
}

++offs;
}

page += SIZE_PAGE;
offs = 0;
}
proc_lockClear(&proc->mapp->lock);

return -1;
}


void vm_mapinfo(meminfo_t *info)
{
rbnode_t *n;
Expand Down
3 changes: 3 additions & 0 deletions vm/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ extern vm_map_t *vm_getSharedMap(int map);
extern int vm_mapBelongs(const struct _process_t *proc, const void *ptr, size_t size);


extern int vm_mapStringBelongs(const struct _process_t *proc, const char *str);


extern int _map_init(vm_map_t *kmap, struct _vm_object_t *kernel, void **start, void **end);


Expand Down
Loading