1 /*
2  * Copyright (c) 2019 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/mutex.h>
9 #include <zephyr/syscall_handler.h>
10 #include <zephyr/kernel_structs.h>
11 
get_k_mutex(struct sys_mutex * mutex)12 static struct k_mutex *get_k_mutex(struct sys_mutex *mutex)
13 {
14 	struct z_object *obj;
15 
16 	obj = z_object_find(mutex);
17 	if (obj == NULL || obj->type != K_OBJ_SYS_MUTEX) {
18 		return NULL;
19 	}
20 
21 	return obj->data.mutex;
22 }
23 
check_sys_mutex_addr(struct sys_mutex * addr)24 static bool check_sys_mutex_addr(struct sys_mutex *addr)
25 {
26 	/* sys_mutex memory is never touched, just used to lookup the
27 	 * underlying k_mutex, but we don't want threads using mutexes
28 	 * that are outside their memory domain
29 	 */
30 	return Z_SYSCALL_MEMORY_WRITE(addr, sizeof(struct sys_mutex));
31 }
32 
z_impl_z_sys_mutex_kernel_lock(struct sys_mutex * mutex,k_timeout_t timeout)33 int z_impl_z_sys_mutex_kernel_lock(struct sys_mutex *mutex, k_timeout_t timeout)
34 {
35 	struct k_mutex *kernel_mutex = get_k_mutex(mutex);
36 
37 	if (kernel_mutex == NULL) {
38 		return -EINVAL;
39 	}
40 
41 	return k_mutex_lock(kernel_mutex, timeout);
42 }
43 
z_vrfy_z_sys_mutex_kernel_lock(struct sys_mutex * mutex,k_timeout_t timeout)44 static inline int z_vrfy_z_sys_mutex_kernel_lock(struct sys_mutex *mutex,
45 						 k_timeout_t timeout)
46 {
47 	if (check_sys_mutex_addr(mutex)) {
48 		return -EACCES;
49 	}
50 
51 	return z_impl_z_sys_mutex_kernel_lock(mutex, timeout);
52 }
53 #include <syscalls/z_sys_mutex_kernel_lock_mrsh.c>
54 
z_impl_z_sys_mutex_kernel_unlock(struct sys_mutex * mutex)55 int z_impl_z_sys_mutex_kernel_unlock(struct sys_mutex *mutex)
56 {
57 	struct k_mutex *kernel_mutex = get_k_mutex(mutex);
58 
59 	if (kernel_mutex == NULL || kernel_mutex->lock_count == 0) {
60 		return -EINVAL;
61 	}
62 
63 	return k_mutex_unlock(kernel_mutex);
64 }
65 
z_vrfy_z_sys_mutex_kernel_unlock(struct sys_mutex * mutex)66 static inline int z_vrfy_z_sys_mutex_kernel_unlock(struct sys_mutex *mutex)
67 {
68 	if (check_sys_mutex_addr(mutex)) {
69 		return -EACCES;
70 	}
71 
72 	return z_impl_z_sys_mutex_kernel_unlock(mutex);
73 }
74 #include <syscalls/z_sys_mutex_kernel_unlock_mrsh.c>
75