diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/include/arch/aarch64/param.h | 35 | ||||
-rw-r--r-- | sys/include/arch/amd64/param.h | 35 | ||||
-rw-r--r-- | sys/include/net/netbuf.h | 2 | ||||
-rw-r--r-- | sys/include/sys/limits.h | 3 | ||||
-rw-r--r-- | sys/include/sys/param.h | 10 | ||||
-rw-r--r-- | sys/include/sys/proc.h | 3 | ||||
-rw-r--r-- | sys/include/sys/socket.h | 97 | ||||
-rw-r--r-- | sys/include/sys/socketvar.h | 53 | ||||
-rw-r--r-- | sys/include/sys/syscall.h | 4 | ||||
-rw-r--r-- | sys/include/sys/uio.h | 51 | ||||
-rw-r--r-- | sys/include/sys/vnode.h | 1 | ||||
-rw-r--r-- | sys/include/sys/vsr.h | 165 | ||||
-rw-r--r-- | sys/kern/kern_socket.c | 447 | ||||
-rw-r--r-- | sys/kern/kern_syscall.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_uio.c | 156 | ||||
-rw-r--r-- | sys/kern/kern_vsr.c | 344 |
16 files changed, 1411 insertions, 0 deletions
diff --git a/sys/include/arch/aarch64/param.h b/sys/include/arch/aarch64/param.h new file mode 100644 index 0000000..c074ffb --- /dev/null +++ b/sys/include/arch/aarch64/param.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AARCH64_PARAM_H_ +#define _AARCH64_PARAM_H_ + +#define M_WORD_SIZE 4 + +#endif /* !_AARCH64_PARAM_H_ */ diff --git a/sys/include/arch/amd64/param.h b/sys/include/arch/amd64/param.h new file mode 100644 index 0000000..6ea3fca --- /dev/null +++ b/sys/include/arch/amd64/param.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AMD64_PARAM_H_ +#define _AMD64_PARAM_H_ + +#define M_WORD_SIZE 8 + +#endif /* !_AMD64_PARAM_H_ */ diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 33ba06f..7067370 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -30,6 +30,8 @@ #ifndef _NET_NETBUF_H_ #define _NET_NETBUF_H_ +#include <sys/types.h> + #define NETBUF_LEN 256 struct netbuf { diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h index f6aed9d..c0ce5af 100644 --- a/sys/include/sys/limits.h +++ b/sys/include/sys/limits.h @@ -36,4 +36,7 @@ #define ARG_MAX 4096 #define CHAR_BIT 8 #define CPU_MAX 256 +#define VSR_MAX_DOMAIN 16 +#define VSR_MAX_CAPSULE 16 +#define IOVEC_MAX 512 #endif /* !_SYS_LIMITS_H_ */ diff --git a/sys/include/sys/param.h b/sys/include/sys/param.h index 7331d5f..2bbbabd 100644 --- a/sys/include/sys/param.h +++ b/sys/include/sys/param.h @@ -30,11 +30,20 @@ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ +#if defined(_KERNEL) +#include <machine/param.h> +#endif + /* Assumed cache line size */ #ifndef COHERENCY_UNIT #define COHERENCY_UNIT 64 #endif +/* Assumed machine word size */ +#ifndef M_WORD_SIZE +#define M_WORD_SIZE 4 +#endif + /* Bit related macros */ #define ISSET(v, f) ((v) & (f)) #define BIT(n) (1ULL << (n)) @@ -47,6 +56,7 @@ /* Align up/down a value */ #define ALIGN_DOWN(value, align) ((value) & ~((align)-1)) #define ALIGN_UP(value, align) (((value) + (align)-1) & ~((align)-1)) +#define MALIGN(value) ALIGN_UP((value), M_WORD_SIZE) /* Bitmap helper macros */ #define setbit(a, b) ((a)[(b) >> 3] |= BIT(b % 8)) diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 9cc9238..89fe638 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -39,6 +39,8 @@ #include <sys/syscall.h> #include <sys/exec.h> #include <sys/ucred.h> +#include <sys/limits.h> +#include <sys/vsr.h> #include <sys/filedesc.h> #include <sys/signal.h> #include <sys/vnode.h> @@ -88,6 +90,7 @@ struct proc { struct ucred cred; struct ksiginfo *ksig_list[PROC_SIGMAX]; struct filedesc *fds[PROC_MAX_FILEDES]; + struct vsr_domain *vsr_tab[VSR_MAX_DOMAIN]; struct mmap_lgdr *mlgdr; struct vcache *vcache; struct spinlock vcache_lock; diff --git a/sys/include/sys/socket.h b/sys/include/sys/socket.h new file mode 100644 index 0000000..f01e2bf --- /dev/null +++ b/sys/include/sys/socket.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_SOCKET_H_ +#define _SYS_SOCKET_H_ + +#include <sys/socketvar.h> +#if defined(_KERNEL) +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/mutex.h> +#else +#include <stdint.h> +#include <stddef.h> +#endif /* _KERNEL */ + +#ifndef _SA_FAMILY_T_DEFINED_ +#define _SA_FAMILY_T_DEFINED_ +typedef uint32_t sa_family_t; +#endif /* _SA_FAMILY_T_DEFINED_ */ + +#ifndef _SOCKLEN_T_DEFINED_ +#define _SOCKLEN_T_DEFINED_ +typedef uint32_t socklen_t; +#endif /* !_SOCKLEN_T_DEFINED_ */ + +/* + * Address family defines + */ +#define AF_UNSPEC 0 +#define AF_UNIX 1 +#define AF_LOCAL AF_UNIX + +/* Socket types */ +#define SOCK_STREAM 1 + +struct sockaddr_un { + sa_family_t sun_family; + char sun_path[108]; +}; + +struct sockaddr { + sa_family_t sa_family; + char sa_data[14]; +}; + +#if defined(_KERNEL) + +struct ksocket { + int sockfd; + union { + struct sockaddr sockaddr; + struct sockaddr_un un; + }; + struct sockbuf buf; + struct mutex *mtx; +}; + +scret_t sys_socket(struct syscall_args *scargs); +scret_t sys_bind(struct syscall_args *scargs); +scret_t sys_recv(struct syscall_args *scargs); +scret_t sys_send(struct syscall_args *scargs); +#endif /* _KERNEL */ + +int socket(int domain, int type, int protocol); +int bind(int sockfd, const struct sockaddr *addr, socklen_t len); + +ssize_t send(int sockfd, const void *buf, size_t size, int flags); +ssize_t recv(int sockfd, void *buf, size_t len, int flags); + +#endif /* !_SYS_SOCKET_H_ */ diff --git a/sys/include/sys/socketvar.h b/sys/include/sys/socketvar.h new file mode 100644 index 0000000..e090a70 --- /dev/null +++ b/sys/include/sys/socketvar.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_SOCKETVAR_H_ +#define _SYS_SOCKETVAR_H_ + +#include <sys/types.h> +#if defined(_KERNEL) +#include <net/netbuf.h> + +/* + * Socket buffer + * + * @buf: Actual data buffer + * @head: Buffer head + * @tail: Buffer tail + * @watermark: Max length + */ +struct sockbuf { + struct netbuf buf; + size_t head; + size_t tail; + size_t watermark; +}; + +#endif /* _KERNEL */ +#endif /* !_SYS_SOCKETVAR_H_ */ diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 02629a9..51a1016 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -59,6 +59,10 @@ #define SYS_setuid 18 #define SYS_getuid 19 #define SYS_waitpid 20 +#define SYS_socket 21 +#define SYS_bind 22 +#define SYS_recv 23 +#define SYS_send 24 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/include/sys/uio.h b/sys/include/sys/uio.h new file mode 100644 index 0000000..d1d4c65 --- /dev/null +++ b/sys/include/sys/uio.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_UIO_H_ +#define _SYS_UIO_H_ + +#if defined(_KERNEL) +#include <sys/types.h> +#else +#include <stdint.h> +#include <stddef.h> +#endif /* _KERNEL */ + +/* + * POSIX I/O vector + */ +struct iovec { + void *iov_base; + size_t iov_len; +}; + +ssize_t readv(int filedes, const struct iovec *iov, int iovcnt); +ssize_t writev(int filedes, const struct iovec *iov, int iovcnt); + +#endif /* !_SYS_UIO_H_ */ diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h index 3402b02..ff6f995 100644 --- a/sys/include/sys/vnode.h +++ b/sys/include/sys/vnode.h @@ -76,6 +76,7 @@ struct vcache { #define VDIR 0x02 /* Directory */ #define VCHR 0x03 /* Character device */ #define VBLK 0x04 /* Block device */ +#define VSOCK 0x05 /* Socket */ #define VNOVAL -1 diff --git a/sys/include/sys/vsr.h b/sys/include/sys/vsr.h new file mode 100644 index 0000000..e63cce1 --- /dev/null +++ b/sys/include/sys/vsr.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_VSR_H_ +#define _SYS_VSR_H_ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/param.h> +#include <sys/ucred.h> +#include <sys/limits.h> +#if defined(_KERNEL) +#include <sys/mutex.h> +#endif /* _KERNEL */ + +struct proc; + +#define VSR_FILE 0x00000000 /* Represented by file */ + +/* + * Defines the access semantics of whether + * r/w operations should be passed down to the + * global state or soley affecting a per-process + * shallow copy. + */ +typedef uint32_t vsr_mode_t; + +/* + * The Virtual System Resource namespace consists of + * domains containing named "capsules". The domain is + * simply a table indexed by a type value e.g. VSR_FILE + * and a capsule is simply a structure containing global data + * as well as a shallow copy which is controlled locally by the + * process. The capsule also contains various access semantics + * that help the VSR subsystem determine whether the access should + * be passed down globally or virtualized locally within the process. + */ +typedef uint8_t vsr_domain_t; + +/* + * VSR mode bits + */ +#define VSR_GLOB_WRITE BIT(0) /* Writes are global */ +#define VSR_GLOB_READ BIT(1) /* Reads are global */ +#define VSR_GLOB_CRED BIT(2) /* Global for specific creds */ + +#if defined(_KERNEL) + +struct vsr_capsule; + +/* + * VSR capsule operations + * + * @reclaim: Cleanup resources + */ +struct capsule_ops { + int(*reclaim)(struct vsr_capsule *cap, int flags); +}; + +/* + * Virtual system resource access + * semantics. + * + * @glob: Global data + * @shallow: Local per process copy + * @mode: VSR mode (see VSR_GLOB_*) + * @cred: Creds (used if VSR_GLOBAL_CRED set) + */ +struct vsr_access { + void *glob; + void *shallow; + vsr_mode_t mode; + struct ucred cred; +}; + +/* + * A virtual system resource capsule containing + * resource owner specific data and hashmap + * buckets. + * + * @name: Capsule name (e.g., "consfeat"), must be freed + * @data: Owner specific data + * @shadow: Local shadow copy (per-process) + * @buckets: Hashmap buckets + * @link: Bucket link + * @ops: Capsule operations + * @lock: Mutex lock protecting fields + */ +struct vsr_capsule { + char *name; + void *data; + void *shadow; + TAILQ_HEAD(, vsr_capsule) buckets; + TAILQ_ENTRY(vsr_capsule) link; + struct capsule_ops ops; + struct mutex lock; +}; + +/* + * Virtual system resource table containg + * VSRs for various types. + * + * Each VSR table belongs to a VSR domain + * (e.g., VSR_FILE). + * + * @ncaps: Number of capsules + * @is_init: Set if hashmap is set up + * @capsules: VSR capsule hashmap + */ +struct vsr_table { + struct vsr_capsule *capsules[VSR_MAX_CAPSULE]; +}; + +/* + * Virtual system resource domain (VSR). + * + * A VSR is represented by a specific VSR type + * (see VSR_*). Each VSR has a table of VSR capsules + * looked up by a VSR capsule name. + * + * One per process. + * + * @type: VSR type + * @table: VSR table + */ +struct vsr_domain { + int type; + struct vsr_table table; +}; + +void vsr_init_domains(struct proc *td); +void vsr_destroy_domains(struct proc *td); + +struct vsr_domain *vsr_new_domain(struct proc *td, vsr_domain_t type); +struct vsr_capsule *vsr_new_capsule(struct proc *td, vsr_domain_t type, const char *name); +struct vsr_capsule *vsr_lookup_capsule(struct proc *td, vsr_domain_t type, const char *name); + +#endif /* _KERNEL */ +#endif /* !_SYS_VSR_H_ */ diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c new file mode 100644 index 0000000..a6cc8d2 --- /dev/null +++ b/sys/kern/kern_socket.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/socket.h> +#include <sys/sio.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/syslog.h> +#include <sys/filedesc.h> +#include <sys/vnode.h> +#include <vm/dynalloc.h> +#include <string.h> + +#define pr_trace(fmt, ...) kprintf("socket: " fmt, ##__VA_ARGS__) +#define pr_error(...) pr_trace(__VA_ARGS__) + +static struct vops socket_vops; + +/* + * Get a kernel socket structure from a + * file descriptor. + * + * @sockfd: File descriptor to lookup + * @res: Result pointer + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +static int +get_ksock(int sockfd, struct ksocket **res) +{ + struct ksocket *ksock; + struct filedesc *fdesc; + struct vnode *vp; + + if (res == NULL) { + return -EINVAL; + } + + /* Grab the file descriptor */ + fdesc = fd_get(sockfd); + if (fdesc == NULL) { + return -EBADF; + } + + /* Is this even a socket? */ + if ((vp = fdesc->vp) == NULL) { + return -ENOTSOCK; + } + if (vp->type != VSOCK) { + return -ENOTSOCK; + } + + ksock = vp->data; + if (__unlikely(ksock == NULL)) { + return -EIO; + } + + *res = ksock; + return 0; +} + +/* + * VFS reclaim callback for the socket + * layer + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +static int +socket_reclaim(struct vnode *vp) +{ + struct ksocket *ksock; + + /* Is this even a socket? */ + if (vp->type != VSOCK) { + return -ENOTSOCK; + } + + /* Is there any data attached? */ + if ((ksock = vp->data) == NULL) { + return -EIO; + } + + fd_close(ksock->sockfd); + mutex_free(ksock->mtx); + dynfree(ksock); + return 0; +} + +/* + * Send data to socket - POSIX send(2) core + * + * @sockfd: File descriptor that backs this socket + * @buf: Buffer containing data to transmit + * @size: Size of the buffer + * @flags: Optional flags + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +ssize_t +send(int sockfd, const void *buf, size_t size, int flags) +{ + struct ksocket *ksock; + struct sockbuf *sbuf; + struct netbuf *netbuf; + size_t tail; + int error; + + /* Size cannot be zero */ + if (size == 0) { + return -EINVAL; + } + + if ((error = get_ksock(sockfd, &ksock)) < 0) { + return error; + } + + sbuf = &ksock->buf; + netbuf = &sbuf->buf; + mutex_acquire(ksock->mtx, 0); + + /* Make sure we dont overflow */ + if (netbuf->len > sbuf->watermark) { + mutex_release(ksock->mtx); + return -ENOBUFS; + } + + if (netbuf->len == 0) { + sbuf->head = 0; + sbuf->tail = 0; + } + + /* Clamp the size if needed */ + if ((netbuf->len + size) > sbuf->watermark) { + size = sbuf->watermark - netbuf->len; + } + if (size == 0) { + return -ENOBUFS; + } + + /* Copy the new data */ + tail = sbuf->tail; + memcpy(&netbuf->data[tail], buf, size); + + sbuf->tail += size; + netbuf->len += size; + mutex_release(ksock->mtx); + return size; +} + +/* + * Recv data from socket - POSIX recv(2) core + * + * @sockfd: File descriptor that backs this socket + * @buf: RX buffer + * @size: Size of the buffer + * @flags: Optional flags + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +ssize_t +recv(int sockfd, void *buf, size_t len, int flags) +{ + struct ksocket *ksock; + struct sockbuf *sbuf; + struct netbuf *netbuf; + size_t head; + int error; + + /* Length cannot be zero */ + if (len == 0) { + return -EINVAL; + } + + if ((error = get_ksock(sockfd, &ksock)) < 0) { + return error; + } + + sbuf = &ksock->buf; + netbuf = &sbuf->buf; + mutex_acquire(ksock->mtx, 0); + + /* Is it empty? */ + if (netbuf->len == 0) { + sbuf->head = 0; + sbuf->tail = 0; + return -EAGAIN; + } + + if (len > netbuf->len) { + len = netbuf->len; + } + + head = sbuf->head; + memcpy(buf, &netbuf->data[head], len); + + sbuf->head = (sbuf->head + len) % NETBUF_LEN; + mutex_release(ksock->mtx); + return len; +} + +/* + * POSIX socket(7) core + * + * @domain: Address family (see AF_*) + * @type: Socket type + * @protocol: Socket protocol + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +int +socket(int domain, int type, int protocol) +{ + struct vnode *vp = NULL; + struct ksocket *ksock = NULL; + struct filedesc *fdesc = NULL; + struct sockbuf *sbuf = NULL; + int fd, error = -1; + + if ((error = fd_alloc(&fdesc)) < 0) { + return error; + } + + fd = fdesc->fdno; + + /* Grab a new socket vnode */ + if ((error = vfs_alloc_vnode(&vp, VSOCK)) < 0) { + fd_close(fd); + return error; + } + + if (vp == NULL) { + error = -ENOBUFS; + goto fail; + } + + ksock = dynalloc(sizeof(*ksock)); + if (ksock == NULL) { + error = -ENOMEM; + goto fail; + } + + fdesc->vp = vp; + vp->vops = &socket_vops; + + sbuf = &ksock->buf; + sbuf->head = 0; + sbuf->tail = 0; + + switch (domain) { + case AF_UNIX: + { + struct sockaddr_un *un; + + un = &ksock->un; + sbuf->watermark = NETBUF_LEN; + + /* + * XXX: We could allow actual paths within the + * file system for sockets. + */ + un->sun_family = domain; + un->sun_path[0] = '\0'; + vp->data = ksock; + } + return fd; + default: + error = -EINVAL; + break; + } + +fail: + if (ksock != NULL) + dynfree(ksock); + if (vp != NULL) + vfs_release_vnode(vp); + + fd_close(fd); + return error; +} + +/* + * Bind address to socket - POSIX bind(2) core + * + * @sockfd: File descriptor + * @addr: Address to bind + * @len: Sockaddr len + * + * Returns zero on success, otherwise a less + * than zero errno. + */ +int +bind(int sockfd, const struct sockaddr *addr, socklen_t len) +{ + struct ksocket *ksock; + int error; + + if ((error = get_ksock(sockfd, &ksock)) < 0) { + kprintf("error=%d\n", error); + return error; + } + + /* Create the new mutex lock */ + ksock->mtx = mutex_new("ksocket"); + if (ksock->mtx == NULL) { + return -ENOMEM; + } + return 0; +} + +/* + * socket(7) syscall + * + * arg0: domain + * arg1: type + * arg2: protocol + */ +scret_t +sys_socket(struct syscall_args *scargs) +{ + int domain = scargs->arg0; + int type = scargs->arg1; + int protocol = scargs->arg2; + + return socket(domain, type, protocol); +} + +/* + * bind(2) syscall + * + * arg0: sockfd + * arg1: addr + * arg2: len + */ +scret_t +sys_bind(struct syscall_args *scargs) +{ + const struct sockaddr *u_addr = (void *)scargs->arg1; + struct sockaddr addr_copy; + int sockfd = scargs->arg0; + int len = scargs->arg2; + int error; + + error = copyin(u_addr, &addr_copy, sizeof(addr_copy)); + if (error < 0) { + return error; + } + + return bind(sockfd, &addr_copy, len); +} + +/* + * recv(2) syscall + * + * arg0: sockfd + * arg1: buf + * arg2: size + * arg3: flags + */ +scret_t +sys_recv(struct syscall_args *scargs) +{ + char buf[NETBUF_LEN]; + void *u_buf = (void *)scargs->arg1; + int sockfd = scargs->arg0; + size_t len = scargs->arg2; + int error, flags = scargs->arg3; + + if (len > sizeof(buf)) { + return -ENOBUFS; + } + + error = recv(sockfd, buf, len, flags); + if (error < 0) { + pr_error("sys_recv: recv() fail (fd=%d)\n", sockfd); + return error; + } + + error = copyout(buf, u_buf, len); + return (error == 0) ? len : error; +} + +/* + * send(2) syscall + * + * arg0: sockfd + * arg1: buf + * arg2: size + * arg3: flags + */ +scret_t +sys_send(struct syscall_args *scargs) +{ + char buf[NETBUF_LEN]; + const void *u_buf = (void *)scargs->arg1; + int sockfd = scargs->arg0; + size_t len = scargs->arg2; + int error, flags = scargs->arg3; + + if (len > sizeof(buf)) { + return -ENOBUFS; + } + + error = copyin(u_buf, buf, len); + if (error < 0) { + pr_error("sys_send: copyin() failure (fd=%d)\n", sockfd); + return error; + } + + return send(sockfd, buf, len, flags); +} + +static struct vops socket_vops = { + .read = NULL, + .write = NULL, + .reclaim = socket_reclaim, +}; diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index cb7e1d2..dd3de4f 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -29,6 +29,7 @@ #include <sys/syscall.h> #include <sys/sysctl.h> +#include <sys/socket.h> #include <sys/reboot.h> #include <sys/types.h> #include <sys/ucred.h> @@ -60,6 +61,10 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_setuid, /* SYS_setuid */ sys_getuid, /* SYS_getuid */ sys_waitpid, /* SYS_waitpid */ + sys_socket, /* SYS_socket */ + sys_bind, /* SYS_bind */ + sys_recv, /* SYS_recv */ + sys_send, /* SYS_send */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); diff --git a/sys/kern/kern_uio.c b/sys/kern/kern_uio.c new file mode 100644 index 0000000..dd533c2 --- /dev/null +++ b/sys/kern/kern_uio.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/limits.h> +#include <sys/errno.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <sys/filedesc.h> + +/* + * Read data into POSIX.1‐2017 iovec + * + * @filedes: File descriptor number + * @iov: I/O vector to read file into + * @iovnt: Number of I/O vectors + */ +ssize_t +readv(int filedes, const struct iovec *iov, int iovcnt) +{ + void *base; + size_t len; + ssize_t tmp, bytes_read = 0; + + if (filedes < 0) { + return -EINVAL; + } + + /* + * Make sure that this conforms to our max + * iovec limit. + */ + if (iovcnt > IOVEC_MAX) { + return -EINVAL; + } + + /* + * Go through each I/O vector and read a chunk + * of data into one. + */ + for (int i = 0; i < iovcnt; ++i) { + base = iov[i].iov_base; + len = iov[i].iov_len; + + /* + * If we encounter a base that is NULL, + * or if the length to read is an invalid + * value of zero. We can just assume this + * is some sort of weird list termination? + */ + if (base == NULL || len == 0) { + break; + } + + /* Read the file into this base */ + tmp = fd_read(filedes, base, len); + + /* Did anything go wrong? */ + if (tmp < 0) { + return tmp; + } + + /* No more data */ + if (tmp == 0) { + break; + } + + /* Read more bytes */ + bytes_read += tmp; + } + + return bytes_read; +} + +/* + * Write data from POSIX.1‐2017 iovec + * + * @filedes: File descriptor number + * @iov: I/O vector to write to file + * @iovnt: Number of I/O vectors + */ +ssize_t +writev(int filedes, const struct iovec *iov, int iovcnt) +{ + void *base; + size_t len; + ssize_t bytes_written = 0; + ssize_t tmp; + + if (filedes < 0) { + return -EINVAL; + } + + /* + * Are we within the limits? Return an + * error if not. + */ + if (iovcnt > IOVEC_MAX) { + return -EINVAL; + } + + for (int i = 0; i < iovcnt; ++i) { + base = iov[i].iov_base; + len = iov[i].iov_len; + + /* + * These are invalid, whatever these are, + * terminate our walk through. + */ + if (base == NULL || len == 0) { + break; + } + + /* Write the data from the iovec */ + tmp = fd_write(filedes, base, len); + + /* Was there an error? */ + if (tmp < 0) { + return tmp; + } + + /* No more data to read? */ + if (tmp == 0) { + break; + } + + bytes_written += tmp; + } + + return bytes_written; +} diff --git a/sys/kern/kern_vsr.c b/sys/kern/kern_vsr.c new file mode 100644 index 0000000..c59be1e --- /dev/null +++ b/sys/kern/kern_vsr.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/vsr.h> +#include <sys/proc.h> +#include <sys/param.h> +#include <sys/limits.h> +#include <sys/syslog.h> +#include <vm/dynalloc.h> +#include <string.h> + +#define pr_trace(fmt, ...) kprintf("vsr: " fmt, ##__VA_ARGS__) +#define pr_error(...) pr_trace(__VA_ARGS__) + +static uint32_t +fnv1_hash(const char *s) +{ + uint32_t hash = 2166136261UL; + const uint8_t *p = (uint8_t *)s; + + while (*p != '\0') { + hash ^= *p; + hash = hash * 0x01000193; + ++p; + } + + return hash; +} + +/* + * Add a VSR capsule to a domain. + */ +static void +vsr_domain_add(struct vsr_domain *vsp, struct vsr_capsule *cap) +{ + struct vsr_table *tab; + struct vsr_capsule **slot; + uint32_t hash; + + if (vsp == NULL || cap == NULL) { + return; + } + + if (cap->name == NULL) { + pr_error("vsr_domain_add: cap->name == NULL\n"); + return; + } + + tab = &vsp->table; + hash = fnv1_hash(cap->name); + slot = &tab->capsules[hash % VSR_MAX_CAPSULE]; + + /* If this slot is free, set it */ + if (*slot == NULL) { + *slot = cap; + return; + } + + /* Handle collision */ + TAILQ_INSERT_TAIL(&(*slot)->buckets, cap, link); +} + +/* + * Handle VSR domain hashmap collisions. + * + * @slot: Slot that we have collided with + * @name: Name to lookup + * + * Returns the pointer to the actual capsule if the + * collision has been resolved, otherwise, NULL if the + * entry to look up was not found. + */ +static struct vsr_capsule * +vsr_domain_clash(struct vsr_capsule *slot, const char *name) +{ + struct vsr_capsule *cap_ent; + + TAILQ_FOREACH(cap_ent, &slot->buckets, link) { + if (cap_ent == NULL) { + continue; + } + + if (strcmp(cap_ent->name, name) == 0) { + return cap_ent; + } + } + + return NULL; +} + +/* + * Lookup a capsule within a VSR domain + * by name. + * + * @vsp: Domain to lookup within + * @name: Name to use as lookup key + * + * Returns NULL if no entry was found. + */ +static struct vsr_capsule * +vfs_domain_lookup(struct vsr_domain *vsp, const char *name) +{ + uint32_t hash; + struct vsr_table *tab; + struct vsr_capsule **slot; + + if (vsp == NULL || name == NULL) { + return NULL; + } + + tab = &vsp->table; + hash = fnv1_hash(name); + slot = &tab->capsules[hash % VSR_MAX_CAPSULE]; + + if (*slot == NULL) { + return NULL; + } + + if (strcmp((*slot)->name, name) != 0) { + return vsr_domain_clash(*slot, name); + } + + return *slot; +} + +/* + * Destroy a VSR capsule + * + * @capule: Capsule to destroy + */ +static void +vsr_destroy_capsule(struct vsr_capsule *capsule) +{ + struct vsr_capsule *bucket; + struct capsule_ops *ops; + + if (capsule->name != NULL) { + dynfree(capsule->name); + capsule->name = NULL; + } + + ops = &capsule->ops; + if (ops->reclaim != NULL) { + ops->reclaim(capsule, 0); + } + + TAILQ_FOREACH(bucket, &capsule->buckets, link) { + if (bucket == NULL) { + continue; + } + vsr_destroy_capsule(bucket); + } + + /* Release any held locks */ + mutex_release(&capsule->lock); +} + +/* + * Destroy a VSR table + * + * @tab: Table to destroy. + */ +static void +vsr_destroy_table(struct vsr_table *tab) +{ + struct vsr_capsule *capsule; + + if (tab == NULL) { + pr_error("vsr_destroy_table: tab is NULL\n"); + return; + } + + for (int i = 0; i < VSR_MAX_CAPSULE; ++i) { + if ((capsule = tab->capsules[i]) == NULL) { + continue; + } + + vsr_destroy_capsule(capsule); + } +} + +/* + * Allocate a new VSR capsule and add it to + * VSR domain. + * + * @type: Domain type (e.g., VSR_FILE) + * @name: Capsule name (e.g., "mod0.data") + * @sz: Length of capsulized data + */ +struct vsr_capsule * +vsr_new_capsule(struct proc *td, vsr_domain_t type, const char *name) +{ + struct vsr_capsule *capsule; + struct vsr_domain *domain; + + /* Valid args? */ + if (type >= VSR_MAX_DOMAIN || td == NULL) { + return NULL; + } + + /* + * The VSR domain must be registered for + * us to add any capsules to it. + */ + if ((domain = td->vsr_tab[type]) == NULL) { + pr_error("VSR domain %d not registered\n", type); + return NULL; + } + + /* Allocate a new capsule */ + capsule = dynalloc(sizeof(*capsule)); + if (capsule == NULL) { + return NULL; + } + + memset(capsule, 0, sizeof(*capsule)); + capsule->name = strdup(name); + + TAILQ_INIT(&capsule->buckets); + vsr_domain_add(domain, capsule); + return capsule; +} + +/* + * Allocate a new VSR domain and add it to + * a specific process. + * + * @type: VSR type (e.g., VSR_FILE) + */ +struct vsr_domain * +vsr_new_domain(struct proc *td, vsr_domain_t type) +{ + struct vsr_domain *domain; + + /* Valid args? */ + if (type >= VSR_MAX_DOMAIN || td == NULL) { + return NULL; + } + + /* + * Do not overwrite the entry if it is + * already allocated and log this anomalous + * activity. + */ + if (td->vsr_tab[type] != NULL) { + pr_error("[security]: type %d already allocated\n", type); + return NULL; + } + + domain = dynalloc(sizeof(*domain)); + if (domain == NULL) { + return NULL; + } + + /* Initialize the domain */ + memset(domain, 0, sizeof(*domain)); + domain->type = type; + + td->vsr_tab[type] = domain; + return domain; +} + +/* + * Lookup a capsule by name for the current + * process. + */ +struct vsr_capsule * +vsr_lookup_capsule(struct proc *td, vsr_domain_t type, const char *name) +{ + struct vsr_domain *domain; + + if (td == NULL) { + return NULL; + } + + /* + * The VSR domain must be registered for + * us to lookup any capsules from it. + */ + if ((domain = td->vsr_tab[type]) == NULL) { + pr_error("VSR domain %d not registered\n", type); + return NULL; + } + + return vfs_domain_lookup(domain, name); +} + +/* + * Initialize per-process domains + */ +void +vsr_init_domains(struct proc *td) +{ + if (vsr_new_domain(td, VSR_FILE) == NULL) { + pr_error("failed to initialize VSR file domain\n"); + } +} + +/* + * Destroy per-process domains + */ +void +vsr_destroy_domains(struct proc *td) +{ + struct vsr_domain *domain; + + if (td == NULL) { + return; + } + + for (int i = 0; i < VSR_MAX_DOMAIN; ++i) { + if ((domain = td->vsr_tab[i]) == NULL) { + continue; + } + + vsr_destroy_table(&domain->table); + } +} |