PatchworkOS
Loading...
Searching...
No Matches
key.c
Go to the documentation of this file.
1#include <kernel/fs/key.h>
2
5#include <kernel/log/panic.h>
9
10#include <errno.h>
11#include <stdlib.h>
12
16
17static key_t key_generate(void)
18{
20
21 key_t key;
22 map_key_t mapKey;
23 do
24 {
25 if (rand_gen(&key, sizeof(key)) == ERR)
26 {
27 panic(NULL, "failed to generate random key");
28 }
29 mapKey = map_key_buffer(&key, sizeof(key));
30 } while (map_get(&keyMap, &mapKey) != NULL);
31
32 return key;
33}
34
35static void key_timer_handler(interrupt_frame_t* frame, cpu_t* self)
36{
37 (void)frame;
38 (void)self;
39
40 clock_t now = timer_uptime();
42
43 key_entry_t* entry;
44 key_entry_t* temp;
45 LIST_FOR_EACH_SAFE(entry, temp, &keyList, entry)
46 {
47 if (entry->expiry > now)
48 {
49 break;
50 }
51
52 map_key_t mapKey = map_key_buffer(&entry->key, sizeof(entry->key));
53 map_remove(&keyMap, &mapKey);
54 list_remove(&keyList, &entry->entry);
55 DEREF(entry->file);
56 free(entry);
57 }
58}
59
60void key_init(void)
61{
62 if (map_init(&keyMap) == ERR)
63 {
64 panic(NULL, "key: failed to initialize key map");
65 }
68}
69
71{
72 if (key == NULL || file == NULL)
73 {
74 errno = EINVAL;
75 return ERR;
76 }
77
78 key_entry_t* entry = malloc(sizeof(key_entry_t));
79 if (entry == NULL)
80 {
81 return ERR;
82 }
83 list_entry_init(&entry->entry);
84 map_entry_init(&entry->mapEntry);
85 entry->key = key_generate();
86 entry->file = REF(file);
87 entry->expiry = timeout == CLOCKS_NEVER ? CLOCKS_NEVER : timer_uptime() + timeout;
88
90 map_key_t mapKey = map_key_buffer(&entry->key, sizeof(entry->key));
91 if (map_insert(&keyMap, &mapKey, &entry->mapEntry) == ERR)
92 {
93 DEREF(entry->file);
94 free(entry);
95 return ERR;
96 }
97
98 *key = entry->key;
99 if (list_length(&keyList) == 0)
100 {
101 list_push(&keyList, &entry->entry);
102 return 0;
103 }
104
105 key_entry_t* other;
106 LIST_FOR_EACH(other, &keyList, entry)
107 {
108 if (entry->expiry < other->expiry)
109 {
110 list_prepend(&keyList, &other->entry, &entry->entry);
111 return 0;
112 }
113 }
114
115 list_push(&keyList, &entry->entry);
116 return 0;
117}
118
120{
121 thread_t* thread = sched_thread();
122 process_t* process = thread->process;
123
124 if (space_check_access(&process->space, key, sizeof(*key)) == ERR)
125 {
126 errno = EFAULT;
127 return ERR;
128 }
129
130 file_t* file = vfs_ctx_get_file(&process->vfsCtx, fd);
131 if (file == NULL)
132 {
133 errno = EBADF;
134 return ERR;
135 }
137
138 key_t keyCopy;
139 if (key_share(&keyCopy, file, timeout) == ERR)
140 {
141 return ERR;
142 }
143
144 if (thread_copy_to_user(thread, key, &keyCopy, sizeof(keyCopy)) == ERR)
145 {
146 return ERR;
147 }
148 return 0;
149}
150
152{
153 if (key == NULL)
154 {
155 errno = EINVAL;
156 return NULL;
157 }
158
160 map_key_t mapKey = map_key_buffer(key, sizeof(*key));
161 map_entry_t* mapEntry = map_get(&keyMap, &mapKey);
162 if (mapEntry == NULL)
163 {
164 errno = ENOENT;
165 return NULL;
166 }
167
168 key_entry_t* entry = CONTAINER_OF(mapEntry, key_entry_t, mapEntry);
169 list_remove(&keyList, &entry->entry);
170 map_remove(&keyMap, &mapKey);
171
172 file_t* file = entry->file;
173 free(entry);
174 return file;
175}
176
178{
179 thread_t* thread = sched_thread();
180 process_t* process = thread->process;
181
182 key_t keyCopy;
183 if (thread_copy_from_user(thread, &keyCopy, key, sizeof(keyCopy)) == ERR)
184 {
185 errno = EFAULT;
186 return ERR;
187 }
188
189 file_t* file = key_claim(&keyCopy);
190 if (file == NULL)
191 {
192 return ERR;
193 }
195
196 return vfs_ctx_alloc_fd(&process->vfsCtx, file);
197}
#define CLOCKS_NEVER
Definition clock_t.h:16
#define SYS_SHARE
Definition syscalls.h:52
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
Definition syscalls.h:100
#define SYS_CLAIM
Definition syscalls.h:53
uint64_t rand_gen(void *buffer, uint64_t size)
Fills a buffer with random bytes.
Definition rand.c:61
void key_init(void)
Initializes the key subsystem.
Definition key.c:60
file_t * key_claim(key_t *key)
Claims a shared file using the provided key.
Definition key.c:151
uint64_t key_share(key_t *key, file_t *file, clock_t timeout)
Generates a key that can be used to retrieve the file within the specified timeout.
Definition key.c:70
fd_t vfs_ctx_alloc_fd(vfs_ctx_t *ctx, file_t *file)
Allocate a new file descriptor in a VFS context.
Definition vfs_ctx.c:142
file_t * vfs_ctx_get_file(vfs_ctx_t *ctx, fd_t fd)
Get a file from a VFS context.
Definition vfs_ctx.c:48
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:362
uint64_t space_check_access(space_t *space, const void *addr, uint64_t length)
Checks if a virtual memory region is within the allowed address range of the space.
Definition space.c:474
uint64_t thread_copy_from_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data from user space.
Definition thread.c:230
uint64_t thread_copy_to_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data to user space.
Definition thread.c:248
thread_t * sched_thread(void)
Retrieves the currently running thread.
Definition sched.c:157
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
Definition rwlock.h:27
void rwlock_init(rwlock_t *lock)
Initializes a rwlock.
Definition rwlock.c:8
#define RWLOCK_WRITE_SCOPE(lock)
Acquires a rwlock for writing for the reminder of the current scope.
Definition rwlock.h:36
clock_t timer_uptime(void)
Time since boot.
Definition timer.c:73
static map_key_t map_key_buffer(const void *buffer, uint64_t length)
Create a map key from a buffer.
Definition map.h:99
void map_entry_init(map_entry_t *entry)
Initialize a map entry.
Definition map.c:71
uint64_t map_insert(map_t *map, const map_key_t *key, map_entry_t *value)
Insert a key-value pair into the map.
Definition map.c:191
uint64_t map_init(map_t *map)
Initialize a map.
Definition map.c:172
void map_remove(map_t *map, const map_key_t *key)
Remove a key-value pair from the map.
Definition map.c:258
map_entry_t * map_get(map_t *map, const map_key_t *key)
Get a value from the map by key.
Definition map.c:236
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define REF(ptr)
Increment reference count.
Definition ref.h:65
#define DEREF(ptr)
Decrement reference count.
Definition ref.h:80
#define ENOENT
No such file or directory.
Definition errno.h:42
#define EINVAL
Invalid argument.
Definition errno.h:142
#define EFAULT
Bad address.
Definition errno.h:102
#define errno
Error number variable.
Definition errno.h:27
#define EBADF
Bad file number.
Definition errno.h:77
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:65
static uint64_t list_length(list_t *list)
Gets the length of the list.
Definition list.h:248
static void list_prepend(list_t *list, list_entry_t *head, list_entry_t *entry)
Prepends an entry to the list.
Definition list.h:305
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
Definition list.h:81
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
Definition list.h:317
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:345
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
Definition list.h:184
static void list_init(list_t *list)
Initializes a list.
Definition list.h:198
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define CONTAINER_OF(ptr, type, member)
Container of macro.
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
static list_t keyList
Definition key.c:14
static rwlock_t keyLock
Definition key.c:15
static key_t key_generate(void)
Definition key.c:17
static map_t keyMap
Definition key.c:13
static void key_timer_handler(interrupt_frame_t *frame, cpu_t *self)
Definition key.c:35
static dentry_t * file
Definition log_file.c:17
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
CPU structure.
Definition cpu.h:42
File structure.
Definition file.h:37
Trap Frame Structure.
Definition interrupt.h:42
Key entry.
Definition key.h:25
clock_t expiry
Definition key.h:30
key_t key
Definition key.h:28
list_entry_t entry
Used to store the key entry in a time sorted list.
Definition key.h:26
file_t * file
Definition key.h:29
map_entry_t mapEntry
Used to store the key entry in a map for fast lookup.
Definition key.h:27
Key type.
Definition io.h:503
A doubly linked list.
Definition list.h:51
Map entry structure.
Definition map.h:57
Map key stucture.
Definition map.h:45
Hash map structure.
Definition map.h:76
Process structure.
Definition process.h:53
space_t space
Definition process.h:59
vfs_ctx_t vfsCtx
Definition process.h:61
Read-Write Ticket Lock structure.
Definition rwlock.h:59
Thread of execution structure.
Definition thread.h:55
process_t * process
The parent process that the thread executes within.
Definition thread.h:57