Skip to content

Commit 48bd8ac

Browse files
committed
Improve input validation of system call
This commit revents crashes from invalid parameters. In addition, it adds missing ERR_TASK_CANT_REMOVE error code definition.
1 parent 98fbddc commit 48bd8ac

File tree

2 files changed

+106
-31
lines changed

2 files changed

+106
-31
lines changed

kernel/error.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ static const struct error_code error_desc[] = {
1313
{ERR_TCB_ALLOC, "TCB allocation"},
1414
{ERR_STACK_ALLOC, "stack allocation"},
1515
{ERR_TASK_NOT_FOUND, "task not found"},
16+
{ERR_TASK_CANT_REMOVE, "cannot remove task"},
1617
{ERR_TASK_CANT_SUSPEND, "cannot suspend task"},
1718
{ERR_TASK_CANT_RESUME, "cannot resume task"},
1819
{ERR_TASK_INVALID_PRIO, "invalid task priority"},

kernel/syscall.c

Lines changed: 105 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <sys/task.h>
55

66
#include "private/stdio.h"
7+
#include "private/utils.h"
78

89
/* syscall wrappers */
910
#define _(name, num, rettype, arglist) static rettype _##name arglist;
@@ -18,8 +19,13 @@ static const void *syscall_table[SYS_COUNT] = {SYSCALL_TABLE};
1819
/* Weak, generic dispatcher */
1920
int syscall(int num, void *a1, void *a2, void *a3)
2021
{
21-
if (num <= 0 || num >= SYS_COUNT)
22+
if (unlikely(num <= 0 || num >= SYS_COUNT))
2223
return -ENOSYS;
24+
25+
/* safety check for valid function pointer */
26+
if (unlikely(!syscall_table[num]))
27+
return -ENOSYS;
28+
2329
return ((int (*)(void *, void *, void *)) syscall_table[num])(a1, a2, a3);
2430
}
2531

@@ -84,40 +90,71 @@ static int _sbrk(int incr)
8490
extern uint32_t _end, _stack;
8591
static char *brk = (char *) &_end;
8692
char *prev = brk;
87-
if (brk + incr >= (char *) &_stack) {
93+
94+
if (unlikely(incr < 0)) {
95+
errno = EINVAL;
96+
return -1;
97+
}
98+
99+
if (unlikely(brk + incr >= (char *) &_stack)) {
88100
errno = ENOMEM;
89101
return -1;
90102
}
103+
91104
brk += incr;
92105
return (int) prev;
93106
}
94107

95108
static int _usleep(int usec)
96109
{
110+
if (unlikely(usec < 0)) {
111+
errno = EINVAL;
112+
return -1;
113+
}
114+
97115
errno = EINTR;
98116
return 0;
99117
}
100118

101119
static int _stat(char *file, struct stat *st)
102120
{
121+
if (unlikely(!st)) {
122+
errno = EFAULT;
123+
return -1;
124+
}
125+
103126
st->st_mode = S_IFCHR;
104127
return 0;
105128
}
106129

107130
static int _open(char *path, int flags)
108131
{
132+
errno = ENOENT;
109133
return -1;
110134
}
111135

112136
static int _close(int file)
113137
{
138+
if (unlikely(file < 0)) {
139+
errno = EBADF;
140+
return -1;
141+
}
114142
return -1;
115143
}
116144

117145
static int _read(int file, char *ptr, int len)
118146
{
119-
int idx;
147+
if (unlikely(!ptr || len < 0)) {
148+
errno = EFAULT;
149+
return -1;
150+
}
151+
152+
if (unlikely(file < 0)) {
153+
errno = EBADF;
154+
return -1;
155+
}
120156

157+
int idx;
121158
for (idx = 0; idx < len; idx++)
122159
*ptr++ = _getchar();
123160

@@ -126,8 +163,17 @@ static int _read(int file, char *ptr, int len)
126163

127164
static int _write(int file, char *ptr, int len)
128165
{
129-
int idx;
166+
if (unlikely(!ptr || len < 0)) {
167+
errno = EFAULT;
168+
return -1;
169+
}
170+
171+
if (unlikely(file < 0)) {
172+
errno = EBADF;
173+
return -1;
174+
}
130175

176+
int idx;
131177
for (idx = 0; idx < len; idx++)
132178
_putchar(*ptr++);
133179

@@ -136,37 +182,60 @@ static int _write(int file, char *ptr, int len)
136182

137183
static int _lseek(int file, int ptr, int dir)
138184
{
185+
if (unlikely(file < 0)) {
186+
errno = EBADF;
187+
return -1;
188+
}
139189
return 0;
140190
}
141191

142192
static int _chdir(const char *path)
143193
{
144-
errno = EFAULT;
194+
if (unlikely(!path)) {
195+
errno = EFAULT;
196+
return -1;
197+
}
198+
errno = ENOENT;
145199
return -1;
146200
}
147201

148202
static int _mknod(const char *path, int mode, int dev)
149203
{
150-
errno = EFAULT;
204+
if (unlikely(!path)) {
205+
errno = EFAULT;
206+
return -1;
207+
}
208+
errno = EPERM;
151209
return -1;
152210
}
153211

154212
static int _unlink(char *name)
155213
{
214+
if (unlikely(!name)) {
215+
errno = EFAULT;
216+
return -1;
217+
}
156218
errno = ENOENT;
157219
return -1;
158220
}
159221

160222
static int _link(char *old, char *new)
161223
{
224+
if (unlikely(!old || !new)) {
225+
errno = EFAULT;
226+
return -1;
227+
}
162228
errno = EMLINK;
163229
return -1;
164230
}
165231

166232
/* Linmo syscalls (wrapper implementation) */
167233

168-
int _tadd(void *task, int stack_size)
234+
static int _tadd(void *task, int stack_size)
169235
{
236+
if (unlikely(!task || stack_size <= 0))
237+
return -EINVAL;
238+
170239
return mo_task_spawn(task, stack_size);
171240
}
172241

@@ -175,8 +244,11 @@ int sys_task_add(void *task, int stack_size)
175244
return syscall(SYS_tadd, task, (void *) stack_size, 0);
176245
}
177246

178-
int _tcancel(int id)
247+
static int _tcancel(int id)
179248
{
249+
if (unlikely(id <= 0))
250+
return -EINVAL;
251+
180252
return mo_task_cancel(id);
181253
}
182254

@@ -185,36 +257,36 @@ int sys_task_cancel(int id)
185257
return syscall(SYS_tcancel, (void *) id, 0, 0);
186258
}
187259

188-
int _tyield(void)
260+
static int _tyield(void)
189261
{
190262
mo_task_yield();
191-
192263
return 0;
193264
}
194265

195266
int sys_task_yield(void)
196267
{
197-
syscall(SYS_tyield, 0, 0, 0);
198-
199-
return 0;
268+
return syscall(SYS_tyield, 0, 0, 0);
200269
}
201270

202-
int _tdelay(int ticks)
271+
static int _tdelay(int ticks)
203272
{
204-
mo_task_delay(ticks);
273+
if (unlikely(ticks < 0))
274+
return -EINVAL;
205275

276+
mo_task_delay(ticks);
206277
return 0;
207278
}
208279

209280
int sys_task_delay(int ticks)
210281
{
211-
syscall(SYS_tdelay, (void *) ticks, 0, 0);
212-
213-
return 0;
282+
return syscall(SYS_tdelay, (void *) ticks, 0, 0);
214283
}
215284

216-
int _tsuspend(int id)
285+
static int _tsuspend(int id)
217286
{
287+
if (unlikely(id <= 0))
288+
return -EINVAL;
289+
218290
return mo_task_suspend(id);
219291
}
220292

@@ -223,8 +295,11 @@ int sys_task_suspend(int id)
223295
return syscall(SYS_tsuspend, (void *) id, 0, 0);
224296
}
225297

226-
int _tresume(int id)
298+
static int _tresume(int id)
227299
{
300+
if (unlikely(id <= 0))
301+
return -EINVAL;
302+
228303
return mo_task_resume(id);
229304
}
230305

@@ -233,9 +308,11 @@ int sys_task_resume(int id)
233308
return syscall(SYS_tresume, (void *) id, 0, 0);
234309
}
235310

236-
237-
int _tpriority(int id, int priority)
311+
static int _tpriority(int id, int priority)
238312
{
313+
if (unlikely(id <= 0))
314+
return -EINVAL;
315+
239316
return mo_task_priority(id, priority);
240317
}
241318

@@ -244,7 +321,7 @@ int sys_task_priority(int id, int priority)
244321
return syscall(SYS_tpriority, (void *) id, (void *) priority, 0);
245322
}
246323

247-
int _tid(void)
324+
static int _tid(void)
248325
{
249326
return mo_task_id();
250327
}
@@ -254,21 +331,18 @@ int sys_task_id(void)
254331
return syscall(SYS_tid, 0, 0, 0);
255332
}
256333

257-
int _twfi(void)
334+
static int _twfi(void)
258335
{
259336
mo_task_wfi();
260-
261337
return 0;
262338
}
263339

264340
int sys_task_wfi(void)
265341
{
266-
syscall(SYS_twfi, 0, 0, 0);
267-
268-
return 0;
342+
return syscall(SYS_twfi, 0, 0, 0);
269343
}
270344

271-
int _tcount(void)
345+
static int _tcount(void)
272346
{
273347
return mo_task_count();
274348
}
@@ -278,7 +352,7 @@ int sys_task_count(void)
278352
return syscall(SYS_tcount, 0, 0, 0);
279353
}
280354

281-
int _ticks(void)
355+
static int _ticks(void)
282356
{
283357
return mo_ticks();
284358
}
@@ -288,7 +362,7 @@ int sys_ticks(void)
288362
return syscall(SYS_ticks, 0, 0, 0);
289363
}
290364

291-
int _uptime(void)
365+
static int _uptime(void)
292366
{
293367
return mo_uptime();
294368
}

0 commit comments

Comments
 (0)