From: Petr Tesarik <petr.tesarik1@xxxxxxxxxxxxxxxxxxx> Add SBM_MAP_READONLY() and SBM_MAP_WRITABLE() to the public API to allow mapping kernel buffers directly into the sandbox with no copying. Signed-off-by: Petr Tesarik <petr.tesarik1@xxxxxxxxxxxxxxxxxxx> --- include/linux/sbm.h | 71 +++++++++++++++++++++++++++++++++++++++++++++ kernel/sbm.c | 34 ++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/include/linux/sbm.h b/include/linux/sbm.h index 98fd27cd58d0..dbdc0781349f 100644 --- a/include/linux/sbm.h +++ b/include/linux/sbm.h @@ -181,6 +181,31 @@ static inline void *sbm_add_buf(struct sbm *sbm, struct sbm_buf **list, #define SBM_COPY_INOUT(sbm, buf, size) \ ((typeof(({buf; })))sbm_add_buf((sbm), &(sbm)->io, (buf), (size))) +/** + * sbm_map_readonly() - Map memory for reading. + * @sbm: SBM instance. + * @ptr: Starting virtual address. + * @size: Size in bytes. + * + * Make the specified virtual address range readable in sandbox code. + * + * Return: Address of the buffer, or %NULL on error. + */ +void *sbm_map_readonly(struct sbm *sbm, const void *ptr, size_t size); + +/** + * sbm_map_writable() - Map memory for reading and writing. + * @sbm: SBM instance. + * @ptr: Starting virtual address. + * @size: Size in bytes. + * + * Make the specified virtual address range readable and writable in sandbox + * code. + * + * Return: Address of the buffer, or %NULL on error. + */ +void *sbm_map_writable(struct sbm *sbm, const void *ptr, size_t size); + #ifdef CONFIG_HAVE_ARCH_SBM /** @@ -303,8 +328,54 @@ static inline int sbm_exec(struct sbm *sbm, sbm_func func, void *data) #define SBM_COPY_OUT(sbm, buf, size) __SBM_EVAL(buf) #define SBM_COPY_INOUT(sbm, buf, size) __SBM_EVAL(buf) +static inline void *sbm_map_readonly(struct sbm *sbm, const void *ptr, + size_t size) +{ + return (void *)ptr; +} + +static inline void *sbm_map_writable(struct sbm *sbm, const void *ptr, + size_t size) +{ + return (void *)ptr; +} + #endif /* CONFIG_SANDBOX_MODE */ +/** + * SBM_MAP_READONLY() - Map an input buffer into SBM. + * @sbm: SBM instance. + * @buf: Buffer virtual address. + * @size: Size of the buffer. + * + * Make a read-only mapping of buffer in sandbox mode. + * + * This works with page granularity. If the buffer is not page-aligned, + * some data before and/or after the page is also mappeed into the sandbox. + * The mapping does not ensure guard pages either. + * + * Return: Buffer address in sandbox mode (same as kernel mode). + */ +#define SBM_MAP_READONLY(sbm, buf, size) \ + ((typeof(({buf; })))sbm_map_readonly((sbm), (buf), (size))) + +/** + * SBM_MAP_WRITABLE() - Map an input/output buffer into SBM. + * @sbm: SBM instance. + * @buf: Buffer virtual address. + * @size: Size of the buffer. + * + * Make a writable mapping of buffer in sandbox mode. + * + * This works with page granularity. If the buffer is not page-aligned, + * some data before and/or after the page is also mappeed into the sandbox. + * The mapping does not ensure guard pages either. + * + * Return: Buffer address in sandbox mode (same as kernel mode). + */ +#define SBM_MAP_WRITABLE(sbm, buf, size) \ + ((typeof(({buf; })))sbm_map_writable((sbm), (buf), (size))) + /** * __SBM_MAP() - Convert parameters to comma-separated expressions. * @m: Macro used to convert each pair. diff --git a/kernel/sbm.c b/kernel/sbm.c index df57184f5d87..c832808b538e 100644 --- a/kernel/sbm.c +++ b/kernel/sbm.c @@ -71,6 +71,40 @@ void sbm_destroy(struct sbm *sbm) } EXPORT_SYMBOL(sbm_destroy); +void *sbm_map_readonly(struct sbm *sbm, const void *ptr, size_t size) +{ + struct sbm_buf buf; + + if (sbm->error) + return NULL; + + buf.sbm_ptr = (void *)ptr; + buf.size = size; + sbm->error = arch_sbm_map_readonly(sbm, &buf); + if (sbm->error) + return NULL; + + return buf.sbm_ptr; +} +EXPORT_SYMBOL(sbm_map_readonly); + +void *sbm_map_writable(struct sbm *sbm, const void *ptr, size_t size) +{ + struct sbm_buf buf; + + if (sbm->error) + return NULL; + + buf.sbm_ptr = (void *)ptr; + buf.size = size; + sbm->error = arch_sbm_map_writable(sbm, &buf); + if (sbm->error) + return NULL; + + return buf.sbm_ptr; +} +EXPORT_SYMBOL(sbm_map_writable); + /* Copy input buffers into a sandbox. */ static int sbm_copy_in(struct sbm *sbm) { -- 2.34.1