PatchworkOS  966e257
A non-POSIX operating system.
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#include <kernel/sched/wait.h>
10#include <kernel/sync/rwlock.h>
11
12#include <errno.h>
13#include <kernel/utils/map.h>
14#include <stdlib.h>
15
19
20static key_t key_generate(void)
21{
23
24 key_t key;
25 map_key_t mapKey;
26 do
27 {
28 if (rand_gen(&key, sizeof(key)) == ERR)
29 {
30 panic(NULL, "failed to generate random key");
31 }
32 mapKey = map_key_buffer(&key, sizeof(key));
33 } while (map_get(&keyMap, &mapKey) != NULL);
34
35 return key;
36}
37
38static void key_timer_handler(interrupt_frame_t* frame, cpu_t* self)
39{
40 (void)frame;
41 (void)self;
42
43 clock_t now = clock_uptime();
45
46 key_entry_t* entry;
47 key_entry_t* temp;
48 LIST_FOR_EACH_SAFE(entry, temp, &keyList, entry)
49 {
50 if (entry->expiry > now)
51 {
52 break;
53 }
54
55 map_remove(&keyMap, &entry->mapEntry);
56 list_remove(&keyList, &entry->entry);
57 UNREF(entry->file);
58 free(entry);
59 }
60}
61
63{
64 if (key == NULL || file == NULL)
65 {
66 errno = EINVAL;
67 return ERR;
68 }
69
70 key_entry_t* entry = malloc(sizeof(key_entry_t));
71 if (entry == NULL)
72 {
73 return ERR;
74 }
75 list_entry_init(&entry->entry);
76 map_entry_init(&entry->mapEntry);
77 entry->key = key_generate();
78 entry->file = REF(file);
79 entry->expiry = CLOCKS_DEADLINE(timeout, clock_uptime());
80
82 map_key_t mapKey = map_key_buffer(&entry->key, sizeof(entry->key));
83 if (map_insert(&keyMap, &mapKey, &entry->mapEntry) == ERR)
84 {
85 UNREF(entry->file);
86 free(entry);
87 return ERR;
88 }
89
90 *key = entry->key;
91 if (list_length(&keyList) == 0)
92 {
93 list_push_back(&keyList, &entry->entry);
94 return 0;
95 }
96
97 key_entry_t* other;
98 LIST_FOR_EACH(other, &keyList, entry)
99 {
100 if (entry->expiry < other->expiry)
101 {
102 list_prepend(&keyList, &other->entry, &entry->entry);
103 return 0;
104 }
105 }
106
107 list_push_back(&keyList, &entry->entry);
108 return 0;
109}
110
112{
113 thread_t* thread = sched_thread();
114 process_t* process = thread->process;
115
116 if (space_check_access(&process->space, key, sizeof(*key)) == ERR)
117 {
118 errno = EFAULT;
119 return ERR;
120 }
121
122 file_t* file = file_table_get(&process->fileTable, fd);
123 if (file == NULL)
124 {
125 return ERR;
126 }
128
129 key_t keyCopy;
130 if (key_share(&keyCopy, file, timeout) == ERR)
131 {
132 return ERR;
133 }
134
135 if (thread_copy_to_user(thread, key, &keyCopy, sizeof(keyCopy)) == ERR)
136 {
137 return ERR;
138 }
139 return 0;
140}
141
143{
144 if (key == NULL)
145 {
146 errno = EINVAL;
147 return NULL;
148 }
149
151 map_key_t mapKey = map_key_buffer(key, sizeof(*key));
152 map_entry_t* mapEntry = map_get_and_remove(&keyMap, &mapKey);
153 if (mapEntry == NULL)
154 {
155 errno = ENOENT;
156 return NULL;
157 }
158
159 key_entry_t* entry = CONTAINER_OF(mapEntry, key_entry_t, mapEntry);
160 list_remove(&keyList, &entry->entry);
161
162 file_t* file = entry->file;
163 free(entry);
164 return file;
165}
166
168{
169 thread_t* thread = sched_thread();
170 process_t* process = thread->process;
171
172 key_t keyCopy;
173 if (thread_copy_from_user(thread, &keyCopy, key, sizeof(keyCopy)) == ERR)
174 {
175 errno = EFAULT;
176 return ERR;
177 }
178
179 file_t* file = key_claim(&keyCopy);
180 if (file == NULL)
181 {
182 return ERR;
183 }
185
186 return file_table_alloc(&process->fileTable, file);
187}
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
Definition syscall.h:163
@ SYS_SHARE
Definition syscall.h:95
@ SYS_CLAIM
Definition syscall.h:96
uint64_t rand_gen(void *buffer, uint64_t size)
Fills a buffer with random bytes.
Definition rand.c:61
file_t * file_table_get(file_table_t *table, fd_t fd)
Get a file from its file descriptor.
Definition file_table.c:31
fd_t file_table_alloc(file_table_t *table, file_t *file)
Allocate a new file descriptor for a file.
Definition file_table.c:50
file_t * key_claim(key_t *key)
Claims a shared file using the provided key.
Definition key.c:142
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:62
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:266
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:478
clock_t clock_uptime(void)
Retrieve the time in nanoseconds since boot.
Definition clock.c:99
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:182
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:200
thread_t * sched_thread(void)
Retrieves the currently running thread.
Definition sched.c:612
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
Definition rwlock.h:29
#define RWLOCK_CREATE()
Create a rwlock initializer.
Definition rwlock.h:47
#define RWLOCK_WRITE_SCOPE(lock)
Acquires a rwlock for writing for the reminder of the current scope.
Definition rwlock.h:38
static map_key_t map_key_buffer(const void *buffer, uint64_t length)
Create a map key from a buffer.
Definition map.h:112
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:204
map_entry_t * map_get_and_remove(map_t *map, const map_key_t *key)
Get and remove a key-value pair from the map.
Definition map.c:335
void map_remove(map_t *map, map_entry_t *entry)
Remove a entry from the map.
Definition map.c:353
map_entry_t * map_get(map_t *map, const map_key_t *key)
Get a value from the map by key.
Definition map.c:287
#define MAP_CREATE()
Create a map initializer.
Definition map.h:160
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define REF(ptr)
Increment reference count.
Definition ref.h:65
#define UNREF(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 LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:63
static uint64_t list_length(list_t *list)
Gets the length of the list.
Definition list.h:246
static void list_push_back(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:343
static void list_prepend(list_t *list, list_entry_t *head, list_entry_t *entry)
Prepends an entry to the list.
Definition list.h:303
#define LIST_CREATE(name)
Creates a list initializer.
Definition list.h:174
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
Definition list.h:79
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
Definition list.h:315
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
Definition list.h:182
#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
#define CLOCKS_DEADLINE(timeout, uptime)
Safely calculate deadline from timeout.
Definition clock_t.h:45
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
static list_t keyList
Definition key.c:17
static rwlock_t keyLock
Definition key.c:18
static key_t key_generate(void)
Definition key.c:20
static map_t keyMap
Definition key.c:16
static void key_timer_handler(interrupt_frame_t *frame, cpu_t *self)
Definition key.c:38
static dentry_t * file
Definition log_file.c:22
__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:122
File structure.
Definition file.h:39
Trap Frame Structure.
Definition interrupt.h:146
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:454
A doubly linked list.
Definition list.h:49
Map entry structure.
Definition map.h:68
Map key stucture.
Definition map.h:56
Hash map structure.
Definition map.h:89
Process structure.
Definition process.h:205
file_table_t fileTable
Definition process.h:213
space_t space
Definition process.h:210
Read-Write Ticket Lock structure.
Definition rwlock.h:61
Thread of execution structure.
Definition thread.h:56
process_t * process
The parent process that the thread executes within.
Definition thread.h:57