Skip to main content
CCY4304 · 12th Project · RISC-V xv6

Securing the Kernel.
Protecting Lives.

A medical-device OS security layer built on xv6-riscv: authentication, discretionary access control, and syscall audit logging, designed to the spirit of FDA 2023 guidance and IEC 62443.

18/18Compliance Tests Passed
3Security Phases
Patient Lives Protected

What is this project?

In 2019 Medtronic disclosed that its MiniMed 508 insulin pump could be wirelessly commanded to deliver a lethal overdose, with no authentication required. The root cause was a complete absence of OS-level access controls.

This project retrofits xv6-riscv, MIT's teaching kernel used in OS courses worldwide, with three security layers that mirror the controls a real medical-device OS must provide:

  • User identity and boot-time authentication
  • Inode-level discretionary access control (DAC)
  • Immutable kernel audit trail for every security decision
Read the regulatory context →

Why xv6?

xv6 is intentionally minimal: ~10 000 lines of C, no MMU complexity, no driver jungle. Every security hook you add is immediately visible in context. That makes it the perfect teaching substrate for medical-device OS concepts where every line of kernel code must be auditable.

The kernel runs on qemu-system-riscv64 (virt board). The RISC-V ISA's privilege levels (U/S/M) map cleanly to xv6's user/kernel separation.

Three Security Phases

Each phase is a self-contained kernel modification. Together they satisfy the CIA triad for a medical-device OS.

Auth

Phase 1: Authentication

UID/GID identity added to every xv6 process. SHA-256-style credential lookup from /etc/passwd. Boot-time login enforces identity before any shell access.

struct proc {
  uint uid;   /* user id     */
  uint gid;   /* group id    */
  uint role;  /* 0=user 1=admin */
  char uname[MAXNAME];
  int  authenticated;
};
View implementation →
DAC

Phase 2: File Permissions

Unix rwxrwxrwx mode bits + owner UID/GID on every inode. Four kernel hook points enforce DAC before any read, write, exec, or stat operation.

struct dinode {
  /* ... existing fields ... */
  uint mode;  /* rwxrwxrwx bits */
  uint uid;   /* owner user id  */
  uint gid;   /* owner group id */
};
View implementation →
Audit

Phase 3: Audit Log

A 256-entry kernel ring buffer records every security event with timestamp, UID, syscall, and result. Admin-only audit_read syscall; non-admins receive EPERM.

struct audit_entry {
  uint   timestamp;
  uint   uid;
  int    syscall_num;
  char   filename[MAXPATH];
  int    result;      /* 0=allow -1=deny */
};
View implementation →

Architecture Overview

Security hooks intercept every syscall before kernel resources are touched.

5compliance_test | login.c | user programs
4usys.S syscall stubs → ECALL trap
3Phase 1: auth_check() Phase 2: perm_check() Phase 3: audit_log()
2Modified kernel: proc.c sysfile.c fs.c trap.c
1xv6-riscv hardware (QEMU virt board)
↑ privilege escalation direction (ECALL)

Compliance Report

18 automated tests run on real xv6 inside QEMU. All pass.

compliance_test output
T01: boot as root (admin) PASS
T02: uid=0 after root login PASS
T03: bad password rejected PASS
T04: good password accepted PASS
T05: file owner set on create PASS
T06: world-readable file readable PASS
T07: chmod 000 blocks owner PASS
T08: chmod 644 allows owner read PASS
T09: chown changes owner PASS
T10: admin can read any file PASS
T11: user cannot read root file PASS
T12: audit_read requires admin PASS
T13: audit log non-empty after ops PASS
T14: audit entries contain uid PASS
T15: exec blocked by perm PASS
T16: write blocked by perm PASS
T17: end-to-end medical workflow PASS
T18: role escalation prevented PASS
Result: 18 / 18 tests passed

Team & Course

Course: CCY4304: Operating Systems Security

Lecturer: Prof. Dr. Ayman Adel Abdel-Hamid

Teaching Assistant: Abdelrahman Solyman

Ready to explore the kernel code?

Full source, documentation, and CI pipeline on GitHub.