lib: newlib: add read/write syscalls

The read/write implementations call directly into the console drivers
using the hook mechanism, causing faults if invoked from user mode.

Add system calls for read() and write() such that we do a privilege
elevation first.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2018-03-26 17:07:33 -07:00 committed by Anas Nashif
parent bc94cc1832
commit 12e6aadcb0
2 changed files with 50 additions and 4 deletions

View file

@ -16,6 +16,18 @@
* that need to call into the kernel as system calls
*/
#ifdef CONFIG_NEWLIB_LIBC
/* syscall generation ignores preprocessor, ensure this is defined to ensure
* we don't have compile errors
*/
#define _MLIBC_RESTRICT
__syscall int _zephyr_read(char *buf, int nbytes);
__syscall int _zephyr_write(char *buf, int nbytes);
#else
/* Minimal libc */
__syscall int _zephyr_fputc(int c, FILE *stream);
@ -23,6 +35,8 @@ __syscall int _zephyr_fputc(int c, FILE *stream);
__syscall size_t _zephyr_fwrite(const void *_MLIBC_RESTRICT ptr, size_t size,
size_t nitems, FILE *_MLIBC_RESTRICT stream);
#endif /* CONFIG_NEWLIB_LIBC */
#include <syscalls/libc-hooks.h>
#endif /* ZEPHYR_LIBC_HOOKS_H */

View file

@ -12,6 +12,8 @@
#include <misc/util.h>
#include <kernel_internal.h>
#include <misc/errno_private.h>
#include <misc/libc-hooks.h>
#include <syscall_handler.h>
#define USED_RAM_END_ADDR POINTER_TO_UINT(&_end)
@ -76,8 +78,7 @@ void __stdin_hook_install(unsigned char (*hook)(void))
_stdin_hook = hook;
}
#ifndef CONFIG_POSIX_FS
int _read(int fd, char *buf, int nbytes)
int _impl__zephyr_read(char *buf, int nbytes)
{
int i = 0;
@ -90,9 +91,16 @@ int _read(int fd, char *buf, int nbytes)
}
return i;
}
FUNC_ALIAS(_read, read, int);
int _write(int fd, char *buf, int nbytes)
#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(_zephyr_read, buf, nbytes)
{
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(buf, nbytes));
return _impl__zephyr_read((char *)buf, nbytes);
}
#endif
int _impl__zephyr_write(char *buf, int nbytes)
{
int i;
@ -104,6 +112,30 @@ int _write(int fd, char *buf, int nbytes)
}
return nbytes;
}
#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(_zephyr_write, buf, nbytes)
{
Z_OOPS(Z_SYSCALL_MEMORY_READ(buf, nbytes));
return _impl__zephyr_write((char *)buf, nbytes);
}
#endif
#ifndef CONFIG_POSIX_FS
int _read(int fd, char *buf, int nbytes)
{
ARG_UNUSED(fd);
return _zephyr_read(buf, nbytes);
}
FUNC_ALIAS(_read, read, int);
int _write(int fd, char *buf, int nbytes)
{
ARG_UNUSED(fd);
return _zephyr_write(buf, nbytes);
}
FUNC_ALIAS(_write, write, int);
int _open(const char *name, int mode)