MIT 6.1810 · Lab syscall · 系统调用
在上一个实验中,你使用系统调用编写了一些工具。在本实验中,你将向 xv6 添加一个新的系统调用,帮助你了解它们的工作原理。
在开始编码之前,阅读xv6 手册的第 2 章,以及第 4 章的 4.3 和 4.4 节,以及相关源文件:
要开始实验,切换到 syscall 分支:
$ git fetch
$ git checkout syscall
$ make clean
在许多情况下,print 语句足以调试内核,但有时单步执行代码或获取堆栈回溯很有用。GDB 调试器可以帮忙。
$ make qemu-gdb
# 在另一个窗口启动 gdb
(gdb) b syscall
Breakpoint 1 at 0x80002142: file kernel/syscall.c, line 243.
(gdb) c
Continuing.
(gdb) layout src
(gdb) backtrace
在 answers-syscall.txt 中回答以下问题:
查看回溯输出,哪个函数调用了 syscall?
键入 n 几次以单步执行过 struct proc *p = myproc();。一旦过了这条语句,键入 p /x *p,以十六进制打印当前进程的 proc struct。
p->trapframe->a7 的值是多少?该值代表什么?
CPU 之前处于什么模式?
写下内核 panic 的汇编指令。哪个寄存器对应变量 num?
为什么内核崩溃?提示:查看教材中的图 3-3;地址 0 在内核地址空间中是否映射?
内核 panic 时运行的进程名称是什么?它的进程 ID(pid)是什么?
在这个任务中,你将"沙箱化"一个进程以限制它可以进行的系统调用。例如,可以沙箱化一个进程以禁止打开文件。你将创建一个新的 interpose 系统调用,指定内核应该拒绝哪些系统调用。
interpose 应该接受两个参数:一个整数掩码和一个路径。掩码的位指定要拒绝的系统调用。例如,要阻止进程使用 open 系统调用,它应该调用 interpose(1 << SYS_open, "-")。
$ sandbox 32768 - cat README
cat: cannot open README
$
一些提示:
在这个任务中,你将扩展沙箱以允许基于路径名的掩码 open 和 exec 系统调用。如果 open 或 exec 被掩码但路径名与允许的路径名匹配,则应该允许这些系统调用。
$ sandbox 32768 README grep xv6 README
xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6).
$ sandbox 32768 README grep xv6 x
grep: cannot open x
$
user/secret.c 在其内存中写入一个秘密字符串,然后退出(释放其内存)。你的目标是在 user/attack.c 中添加几行代码,找到前一次执行 secret.c 写入内存的秘密,并单独打印该秘密。
$ secret xyzzy
$ attack
xyzzy
$
本实验故意省略了 uvmalloc() 中的 memset(mem, 0, sz) 和 kalloc.c 中的两行 memset。结果是,新分配的内存保留上次使用的内容。
创建一个新文件 time.txt,放入一个整数,表示你花在实验上的小时数。
将你的答案写在 answers-syscall.txt 中。
运行 make zipball,上传到 Gradescope。