diff --git a/easy-fs-fuse/src/main.rs b/easy-fs-fuse/src/main.rs index 09016c3..39b9eaf 100644 --- a/easy-fs-fuse/src/main.rs +++ b/easy-fs-fuse/src/main.rs @@ -149,3 +149,59 @@ fn efs_test() -> std::io::Result<()> { Ok(()) } + +#[test] +fn mac_test() -> std::io::Result<()> { + const BLOCK_SZ: usize = 512; + + let block_file = Arc::new(BlockFile(Mutex::new({ + let f = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open("target/fs_mac.img")?; + f.set_len(8192 * BLOCK_SZ).unwrap(); + f + }))); + + EasyFileSystem::create(block_file.clone(), 4096, 1); + let efs = EasyFileSystem::open(block_file.clone()); + let root_inode = EasyFileSystem::root_inode(&efs); + + root_inode.create("root_file"); + root_inode.create("public_file"); + + let secret_inode = root_inode.find("root_file").unwrap(); + secret_inode.write_at(0, b"TOP SECRET: root only!"); + let public_inode = root_inode.find("public_file").unwrap(); + public_inode.write_at(0, b"This file is public."); + + let check_permission = |user: &str, filename: &str| -> bool { + if filename == "root_file" && user != "root" { + false + } else { + true + } + }; + + let users = ["root", "nonroot"]; + for user in users.iter() { + println!("{} task:", user); + + for filename in ["root_file", "public_file"].iter() { + if check_permission(user, filename) { + let inode = root_inode.find(filename).unwrap(); + let mut buf = [0u8; 128]; + let len = inode.read_at(0, &mut buf); + let content = core::str::from_utf8(&buf[..len]).unwrap(); + println!("{}: Opened successfully"); + } else { + println!("{}: Permission denied"); + } + } + + println!(); + } + + Ok(()) +} diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index ff68ee9..8d46fad 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -47,6 +47,13 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize { let task = current_task().unwrap(); let token = current_user_token(); let path = translated_str(token, path); + + // 简单用户检查示例:非 root 用户不能打开 /root 下文件 + let username = task.inner_exclusive_access().user.clone(); + if path.starts_with("/root") && username != "root" { + return -1; // Permission denied + } + if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) { let mut inner = task.inner_exclusive_access(); let fd = inner.alloc_fd(); @@ -57,6 +64,7 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize { } } + pub fn sys_close(fd: usize) -> isize { let task = current_task().unwrap(); let mut inner = task.inner_exclusive_access(); diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 7b02cd6..87d287a 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -30,6 +30,9 @@ pub struct TaskControlBlockInner { pub children: Vec>, pub exit_code: i32, pub fd_table: Vec>>, + + // New: User + pub user: String, } impl TaskControlBlockInner { @@ -166,6 +169,7 @@ impl TaskControlBlock { children: Vec::new(), exit_code: 0, fd_table: new_fd_table, + user: username.to_string(), // Init User name }) }, });