forked from Bananymous/banan-os
				
			Kernel/LibC: Implement chroot
This commit is contained in:
		
							parent
							
								
									695262624d
								
							
						
					
					
						commit
						ef6ee78fd1
					
				|  | @ -20,6 +20,6 @@ namespace Kernel::ELF | |||
| 		BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions; | ||||
| 	}; | ||||
| 
 | ||||
| 	BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode>, const Credentials&, PageTable&); | ||||
| 	BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials&, PageTable&); | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -71,13 +71,13 @@ namespace Kernel | |||
| 
 | ||||
| 		File root_file() | ||||
| 		{ | ||||
| 			return File(root_inode(), "/"_sv); | ||||
| 			return File { root_inode(), "/"_sv }; | ||||
| 		} | ||||
| 
 | ||||
| 		BAN::ErrorOr<File> file_from_relative_path(const File& parent, const Credentials&, BAN::StringView, int); | ||||
| 		BAN::ErrorOr<File> file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags) | ||||
| 		BAN::ErrorOr<File> file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials&, BAN::StringView, int); | ||||
| 		BAN::ErrorOr<File> file_from_absolute_path(BAN::RefPtr<Inode> root_inode, const Credentials& credentials, BAN::StringView path, int flags) | ||||
| 		{ | ||||
| 			return file_from_relative_path(root_file(), credentials, path, flags); | ||||
| 			return file_from_relative_path(root_inode, File { root_inode, "/"_sv }, credentials, path, flags); | ||||
| 		} | ||||
| 
 | ||||
| 	private: | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <BAN/WeakPtr.h> | ||||
| #include <kernel/FS/Socket.h> | ||||
| #include <kernel/FS/TmpFS/Inode.h> | ||||
| #include <kernel/FS/VirtualFileSystem.h> | ||||
| #include <kernel/Lock/SpinLock.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
|  | @ -39,8 +40,8 @@ namespace Kernel | |||
| 
 | ||||
| 		BAN::ErrorOr<void> add_packet(BAN::ConstByteSpan); | ||||
| 
 | ||||
| 		bool is_bound() const { return !m_bound_path.empty(); } | ||||
| 		bool is_bound_to_unused() const { return m_bound_path == "X"_sv; } | ||||
| 		bool is_bound() const { return !m_bound_file.canonical_path.empty(); } | ||||
| 		bool is_bound_to_unused() const { return !m_bound_file.inode; } | ||||
| 
 | ||||
| 		bool is_streaming() const; | ||||
| 
 | ||||
|  | @ -63,7 +64,7 @@ namespace Kernel | |||
| 
 | ||||
| 	private: | ||||
| 		const Socket::Type		m_socket_type; | ||||
| 		BAN::String			m_bound_path; | ||||
| 		VirtualFileSystem::File	m_bound_file; | ||||
| 
 | ||||
| 		BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info; | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,6 +76,7 @@ namespace Kernel | |||
| 		BAN::ErrorOr<long> sys_getcwd(char* buffer, size_t size); | ||||
| 		BAN::ErrorOr<long> sys_chdir(const char* path); | ||||
| 		BAN::ErrorOr<long> sys_fchdir(int fildes); | ||||
| 		BAN::ErrorOr<long> sys_chroot(const char* path); | ||||
| 
 | ||||
| 		BAN::ErrorOr<long> sys_setuid(uid_t); | ||||
| 		BAN::ErrorOr<long> sys_setgid(gid_t); | ||||
|  | @ -234,6 +235,7 @@ namespace Kernel | |||
| 		static void update_alarm_queue(); | ||||
| 
 | ||||
| 		const VirtualFileSystem::File& working_directory() const { return m_working_directory; } | ||||
| 		const VirtualFileSystem::File& root_file() const { return m_root_file; } | ||||
| 
 | ||||
| 	private: | ||||
| 		Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp); | ||||
|  | @ -313,6 +315,7 @@ namespace Kernel | |||
| 		mutable Mutex m_process_lock; | ||||
| 
 | ||||
| 		VirtualFileSystem::File m_working_directory; | ||||
| 		VirtualFileSystem::File m_root_file; | ||||
| 
 | ||||
| 		BAN::Vector<Thread*> m_threads; | ||||
| 
 | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ namespace Kernel::ELF | |||
| 		return BAN::move(program_headers); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table) | ||||
| 	BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table) | ||||
| 	{ | ||||
| 		auto file_header = TRY(read_and_validate_file_header(inode)); | ||||
| 		auto program_headers = TRY(read_program_headers(inode, file_header)); | ||||
|  | @ -143,7 +143,7 @@ namespace Kernel::ELF | |||
| 
 | ||||
| 		if (!interpreter.empty()) | ||||
| 		{ | ||||
| 			auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, interpreter, O_EXEC)).inode; | ||||
| 			auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(root, credentials, interpreter, O_EXEC)).inode; | ||||
| 			auto interpreter_file_header = TRY(read_and_validate_file_header(interpreter_inode)); | ||||
| 			auto interpreter_program_headers = TRY(read_program_headers(interpreter_inode, interpreter_file_header)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -186,7 +186,8 @@ namespace Kernel | |||
| 
 | ||||
| 	BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView block_device_path, BAN::StringView target) | ||||
| 	{ | ||||
| 		auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true)); | ||||
| 		// TODO: allow custom root
 | ||||
| 		auto block_device_file = TRY(file_from_absolute_path(root_inode(), credentials, block_device_path, true)); | ||||
| 		if (!block_device_file.inode->is_device()) | ||||
| 			return BAN::Error::from_errno(ENOTBLK); | ||||
| 
 | ||||
|  | @ -200,7 +201,8 @@ namespace Kernel | |||
| 
 | ||||
| 	BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::RefPtr<FileSystem> file_system, BAN::StringView path) | ||||
| 	{ | ||||
| 		auto file = TRY(file_from_absolute_path(credentials, path, true)); | ||||
| 		// TODO: allow custom root
 | ||||
| 		auto file = TRY(file_from_absolute_path(root_inode(), credentials, path, true)); | ||||
| 		if (!file.inode->mode().ifdir()) | ||||
| 			return BAN::Error::from_errno(ENOTDIR); | ||||
| 
 | ||||
|  | @ -227,7 +229,7 @@ namespace Kernel | |||
| 		return nullptr; | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(const File& parent, const Credentials& credentials, BAN::StringView path, int flags) | ||||
| 	BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials& credentials, BAN::StringView path, int flags) | ||||
| 	{ | ||||
| 		LockGuard _(m_mutex); | ||||
| 
 | ||||
|  | @ -269,6 +271,8 @@ namespace Kernel | |||
| 			auto orig = inode; | ||||
| 
 | ||||
| 			// resolve file name
 | ||||
| 			{ | ||||
| 				if (!(inode == root_inode && path_part == ".."_sv)) | ||||
| 				{ | ||||
| 					auto parent_inode = inode; | ||||
| 					if (path_part == ".."_sv) | ||||
|  | @ -277,6 +281,7 @@ namespace Kernel | |||
| 					if (!parent_inode->can_access(credentials, O_SEARCH)) | ||||
| 						return BAN::Error::from_errno(EACCES); | ||||
| 					inode = TRY(parent_inode->find_inode(path_part)); | ||||
| 				} | ||||
| 
 | ||||
| 				if (path_part == ".."_sv) | ||||
| 				{ | ||||
|  | @ -310,7 +315,7 @@ namespace Kernel | |||
| 
 | ||||
| 				if (link_target.front() == '/') | ||||
| 				{ | ||||
| 					inode = root_inode(); | ||||
| 					inode = root_inode; | ||||
| 					canonical_path.clear(); | ||||
| 				} | ||||
| 				else | ||||
|  |  | |||
|  | @ -13,7 +13,15 @@ | |||
| namespace Kernel | ||||
| { | ||||
| 
 | ||||
| 	static BAN::HashMap<BAN::String, BAN::WeakPtr<UnixDomainSocket>>	s_bound_sockets; | ||||
| 	struct UnixSocketHash | ||||
| 	{ | ||||
| 		BAN::hash_t operator()(const BAN::RefPtr<Inode>& socket) | ||||
| 		{ | ||||
| 			return BAN::hash<const Inode*>{}(socket.ptr()); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets; | ||||
| 	static SpinLock s_bound_socket_lock; | ||||
| 
 | ||||
| 	static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE; | ||||
|  | @ -57,9 +65,7 @@ namespace Kernel | |||
| 		if (is_bound() && !is_bound_to_unused()) | ||||
| 		{ | ||||
| 			SpinLockGuard _(s_bound_socket_lock); | ||||
| 			auto it = s_bound_sockets.find(m_bound_path); | ||||
| 			if (it != s_bound_sockets.end()) | ||||
| 				s_bound_sockets.remove(it); | ||||
| 			s_bound_sockets.remove(m_bound_file.inode); | ||||
| 		} | ||||
| 		if (m_info.has<ConnectionInfo>()) | ||||
| 		{ | ||||
|  | @ -117,17 +123,22 @@ namespace Kernel | |||
| 			return_inode = reinterpret_cast<UnixDomainSocket*>(return_inode_tmp.ptr()); | ||||
| 		} | ||||
| 
 | ||||
| 		TRY(return_inode->m_bound_path.push_back('X')); | ||||
| 		TRY(return_inode->m_bound_file.canonical_path.push_back('X')); | ||||
| 		return_inode->m_info.get<ConnectionInfo>().connection = TRY(pending->get_weak_ptr()); | ||||
| 		pending->m_info.get<ConnectionInfo>().connection = TRY(return_inode->get_weak_ptr()); | ||||
| 		pending->m_info.get<ConnectionInfo>().connection_done = true; | ||||
| 
 | ||||
| 		if (address && address_len && !is_bound_to_unused()) | ||||
| 		{ | ||||
| 			size_t copy_len = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr) + m_bound_path.size() + 1); | ||||
| 			auto& sockaddr_un = *reinterpret_cast<struct sockaddr_un*>(address); | ||||
| 			sockaddr_un.sun_family = AF_UNIX; | ||||
| 			strncpy(sockaddr_un.sun_path, pending->m_bound_path.data(), copy_len); | ||||
| 			sockaddr_un sa_un { | ||||
| 				.sun_family = AF_UNIX, | ||||
| 				.sun_path {}, | ||||
| 			}; | ||||
| 			strcpy(sa_un.sun_path, pending->m_bound_file.canonical_path.data()); | ||||
| 
 | ||||
| 			const size_t to_copy = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr_un)); | ||||
| 			memcpy(address, &sa_un, to_copy); | ||||
| 			*address_len = to_copy; | ||||
| 		} | ||||
| 
 | ||||
| 		return TRY(Process::current().open_inode(VirtualFileSystem::File(return_inode, "<unix socket>"_sv), O_RDWR | flags)); | ||||
|  | @ -141,10 +152,11 @@ namespace Kernel | |||
| 		if (sockaddr_un.sun_family != AF_UNIX) | ||||
| 			return BAN::Error::from_errno(EAFNOSUPPORT); | ||||
| 		if (!is_bound()) | ||||
| 			TRY(m_bound_path.push_back('X')); | ||||
| 			TRY(m_bound_file.canonical_path.push_back('X')); | ||||
| 
 | ||||
| 		auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path)); | ||||
| 		auto file = TRY(VirtualFileSystem::get().file_from_absolute_path( | ||||
| 			Process::current().root_file().inode, | ||||
| 			Process::current().credentials(), | ||||
| 			absolute_path, | ||||
| 			O_RDWR | ||||
|  | @ -154,7 +166,7 @@ namespace Kernel | |||
| 
 | ||||
| 		{ | ||||
| 			SpinLockGuard _(s_bound_socket_lock); | ||||
| 			auto it = s_bound_sockets.find(file.canonical_path); | ||||
| 			auto it = s_bound_sockets.find(file.inode); | ||||
| 			if (it == s_bound_sockets.end()) | ||||
| 				return BAN::Error::from_errno(ECONNREFUSED); | ||||
| 			target = it->value.lock(); | ||||
|  | @ -236,7 +248,7 @@ namespace Kernel | |||
| 
 | ||||
| 		// FIXME: This feels sketchy
 | ||||
| 		auto parent_file = bind_path.front() == '/' | ||||
| 			? VirtualFileSystem::get().root_file() | ||||
| 			? TRY(Process::current().root_file().clone()) | ||||
| 			: TRY(Process::current().working_directory().clone()); | ||||
| 		if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error()) | ||||
| 		{ | ||||
|  | @ -245,6 +257,7 @@ namespace Kernel | |||
| 			return ret.release_error(); | ||||
| 		} | ||||
| 		auto file = TRY(VirtualFileSystem::get().file_from_relative_path( | ||||
| 			Process::current().root_file().inode, | ||||
| 			parent_file, | ||||
| 			Process::current().credentials(), | ||||
| 			bind_path, | ||||
|  | @ -252,10 +265,10 @@ namespace Kernel | |||
| 		)); | ||||
| 
 | ||||
| 		SpinLockGuard _(s_bound_socket_lock); | ||||
| 		if (s_bound_sockets.contains(file.canonical_path)) | ||||
| 		if (s_bound_sockets.contains(file.inode)) | ||||
| 			return BAN::Error::from_errno(EADDRINUSE); | ||||
| 		TRY(s_bound_sockets.emplace(file.canonical_path, TRY(get_weak_ptr()))); | ||||
| 		m_bound_path = BAN::move(file.canonical_path); | ||||
| 		TRY(s_bound_sockets.emplace(file.inode, TRY(get_weak_ptr()))); | ||||
| 		m_bound_file = BAN::move(file); | ||||
| 
 | ||||
| 		return {}; | ||||
| 	} | ||||
|  | @ -354,14 +367,21 @@ namespace Kernel | |||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			BAN::String canonical_path; | ||||
| 			BAN::RefPtr<Inode> target_inode; | ||||
| 
 | ||||
| 			if (!address) | ||||
| 			{ | ||||
| 				auto& connectionless_info = m_info.get<ConnectionlessInfo>(); | ||||
| 				if (connectionless_info.peer_address.empty()) | ||||
| 					return BAN::Error::from_errno(EDESTADDRREQ); | ||||
| 				TRY(canonical_path.append(connectionless_info.peer_address)); | ||||
| 
 | ||||
| 				auto absolute_path = TRY(Process::current().absolute_path_of(connectionless_info.peer_address)); | ||||
| 				target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path( | ||||
| 					Process::current().root_file().inode, | ||||
| 					Process::current().credentials(), | ||||
| 					absolute_path, | ||||
| 					O_RDWR | ||||
| 				)).inode; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
|  | @ -372,17 +392,16 @@ namespace Kernel | |||
| 					return BAN::Error::from_errno(EAFNOSUPPORT); | ||||
| 
 | ||||
| 				auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path)); | ||||
| 				auto file = TRY(VirtualFileSystem::get().file_from_absolute_path( | ||||
| 				target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path( | ||||
| 					Process::current().root_file().inode, | ||||
| 					Process::current().credentials(), | ||||
| 					absolute_path, | ||||
| 					O_WRONLY | ||||
| 				)); | ||||
| 
 | ||||
| 				canonical_path = BAN::move(file.canonical_path); | ||||
| 				)).inode; | ||||
| 			} | ||||
| 
 | ||||
| 			SpinLockGuard _(s_bound_socket_lock); | ||||
| 			auto it = s_bound_sockets.find(canonical_path); | ||||
| 			auto it = s_bound_sockets.find(target_inode); | ||||
| 			if (it == s_bound_sockets.end()) | ||||
| 				return BAN::Error::from_errno(EDESTADDRREQ); | ||||
| 			auto target = it->value.lock(); | ||||
|  | @ -449,20 +468,11 @@ namespace Kernel | |||
| 		if (!connection) | ||||
| 			return BAN::Error::from_errno(ENOTCONN); | ||||
| 
 | ||||
| 		sockaddr_un sa_un; | ||||
| 		sa_un.sun_family = AF_UNIX; | ||||
| 		sa_un.sun_path[0] = 0; | ||||
| 
 | ||||
| 		{ | ||||
| 			SpinLockGuard _(s_bound_socket_lock); | ||||
| 			for (auto& [path, socket] : s_bound_sockets) | ||||
| 			{ | ||||
| 				if (socket.lock() != connection) | ||||
| 					continue; | ||||
| 				strcpy(sa_un.sun_path, path.data()); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		sockaddr_un sa_un { | ||||
| 			.sun_family = AF_UNIX, | ||||
| 			.sun_path = {}, | ||||
| 		}; | ||||
| 		strcpy(sa_un.sun_path, connection->m_bound_file.canonical_path.data()); | ||||
| 
 | ||||
| 		const size_t to_copy = BAN::Math::min<socklen_t>(sizeof(sockaddr_un), *address_len); | ||||
| 		memcpy(address, &sa_un, to_copy); | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ namespace Kernel | |||
| 
 | ||||
| 	BAN::ErrorOr<int> OpenFileDescriptorSet::open(BAN::StringView absolute_path, int flags) | ||||
| 	{ | ||||
| 		return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags); | ||||
| 		return open(TRY(VirtualFileSystem::get().file_from_absolute_path(Process::current().root_file().inode, m_credentials, absolute_path, flags)), flags); | ||||
| 	} | ||||
| 
 | ||||
| 	struct SocketInfo | ||||
|  |  | |||
|  | @ -103,6 +103,8 @@ namespace Kernel | |||
| 		auto* process = create_process(credentials, 0); | ||||
| 
 | ||||
| 		process->m_working_directory = VirtualFileSystem::get().root_file(); | ||||
| 		process->m_root_file         = VirtualFileSystem::get().root_file(); | ||||
| 
 | ||||
| 		process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace())); | ||||
| 
 | ||||
| 		TRY(process->m_cmdline.emplace_back()); | ||||
|  | @ -118,7 +120,7 @@ namespace Kernel | |||
| 		auto executable_file = TRY(process->find_file(AT_FDCWD, path.data(), O_EXEC)); | ||||
| 		auto executable_inode = executable_file.inode; | ||||
| 
 | ||||
| 		auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table())); | ||||
| 		auto executable = TRY(ELF::load_from_inode(process->m_root_file.inode, executable_inode, process->m_credentials, process->page_table())); | ||||
| 		process->m_mapped_regions = BAN::move(executable.regions); | ||||
| 
 | ||||
| 		if (executable_inode->mode().mode & +Inode::Mode::ISUID) | ||||
|  | @ -456,7 +458,7 @@ namespace Kernel | |||
| 
 | ||||
| 		auto parent_file = TRY(find_relative_parent(fd, path)); | ||||
| 		auto file = path | ||||
| 			? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)) | ||||
| 			? TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent_file, m_credentials, path, flags)) | ||||
| 			: BAN::move(parent_file); | ||||
| 
 | ||||
| 		return file; | ||||
|  | @ -480,7 +482,7 @@ namespace Kernel | |||
| 
 | ||||
| 		if (auto index = path_sv.rfind('/'); index.has_value()) | ||||
| 		{ | ||||
| 			parent = TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, m_credentials, path_sv.substring(0, index.value()), flags)); | ||||
| 			parent = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, m_credentials, path_sv.substring(0, index.value()), flags)); | ||||
| 			file_name = path_sv.substring(index.value() + 1); | ||||
| 		} | ||||
| 		else | ||||
|  | @ -510,7 +512,7 @@ namespace Kernel | |||
| 		ASSERT(m_process_lock.is_locked()); | ||||
| 
 | ||||
| 		if (path && path[0] == '/') | ||||
| 			return VirtualFileSystem::get().root_file(); | ||||
| 			return TRY(m_root_file.clone()); | ||||
| 
 | ||||
| 		if (fd == AT_FDCWD) | ||||
| 			return TRY(m_working_directory.clone()); | ||||
|  | @ -582,6 +584,7 @@ namespace Kernel | |||
| 		} | ||||
| 
 | ||||
| 		auto working_directory = TRY(m_working_directory.clone()); | ||||
| 		auto root_file         = TRY(m_root_file.clone()); | ||||
| 
 | ||||
| 		BAN::Vector<BAN::String> cmdline; | ||||
| 		TRY(cmdline.resize(m_cmdline.size())); | ||||
|  | @ -604,6 +607,7 @@ namespace Kernel | |||
| 		Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp); | ||||
| 		forked->m_controlling_terminal = m_controlling_terminal; | ||||
| 		forked->m_working_directory = BAN::move(working_directory); | ||||
| 		forked->m_root_file = BAN::move(root_file); | ||||
| 		forked->m_cmdline = BAN::move(cmdline); | ||||
| 		forked->m_environ = BAN::move(environ); | ||||
| 		forked->m_page_table = BAN::move(page_table); | ||||
|  | @ -656,7 +660,7 @@ namespace Kernel | |||
| 			auto executable_file = TRY(find_file(AT_FDCWD, path, O_EXEC)); | ||||
| 			auto executable_inode = executable_file.inode; | ||||
| 
 | ||||
| 			auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, *new_page_table)); | ||||
| 			auto executable = TRY(ELF::load_from_inode(m_root_file.inode, executable_inode, m_credentials, *new_page_table)); | ||||
| 			auto new_mapped_regions = BAN::move(executable.regions); | ||||
| 
 | ||||
| 			BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector; | ||||
|  | @ -1044,7 +1048,7 @@ namespace Kernel | |||
| 		TRY(validate_string_access(path)); | ||||
| 
 | ||||
| 		auto [parent, file_name] = TRY(find_parent_file(fd, path, O_RDONLY)); | ||||
| 		auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags); | ||||
| 		auto file_or_error = VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags); | ||||
| 
 | ||||
| 		VirtualFileSystem::File file; | ||||
| 		if (file_or_error.is_error()) | ||||
|  | @ -1054,7 +1058,7 @@ namespace Kernel | |||
| 
 | ||||
| 			// FIXME: There is a race condition between next two lines
 | ||||
| 			TRY(parent.inode->create_file(file_name, (mode & 0777) | Inode::Mode::IFREG, m_credentials.euid(), m_credentials.egid())); | ||||
| 			file = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags & ~O_RDWR)); | ||||
| 			file = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags & ~O_RDWR)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
|  | @ -1135,7 +1139,7 @@ namespace Kernel | |||
| 		credentials.set_egid(credentials.rgid()); | ||||
| 
 | ||||
| 		auto relative_parent = TRY(find_relative_parent(AT_FDCWD, path)); | ||||
| 		TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, credentials, path, flags)); | ||||
| 		TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, credentials, path, flags)); | ||||
| 
 | ||||
| 		return 0; | ||||
| 	} | ||||
|  | @ -1258,6 +1262,7 @@ namespace Kernel | |||
| 			flag = O_NOFOLLOW; | ||||
| 
 | ||||
| 		LockGuard _(m_process_lock); | ||||
| 		TRY(validate_string_access(path)); | ||||
| 
 | ||||
| 		auto inode = TRY(find_file(fd, path, flag)).inode; | ||||
| 
 | ||||
|  | @ -1280,6 +1285,7 @@ namespace Kernel | |||
| 			flag = O_NOFOLLOW; | ||||
| 
 | ||||
| 		LockGuard _(m_process_lock); | ||||
| 		TRY(validate_string_access(path)); | ||||
| 
 | ||||
| 		auto inode = TRY(find_file(fd, path, flag)).inode; | ||||
| 
 | ||||
|  | @ -2095,22 +2101,25 @@ namespace Kernel | |||
| 	BAN::ErrorOr<long> Process::sys_chdir(const char* path) | ||||
| 	{ | ||||
| 		LockGuard _(m_process_lock); | ||||
| 
 | ||||
| 		TRY(validate_string_access(path)); | ||||
| 
 | ||||
| 		auto file = TRY(find_file(AT_FDCWD, path, O_SEARCH)); | ||||
| 		m_working_directory = BAN::move(file); | ||||
| 
 | ||||
| 		m_working_directory = TRY(find_file(AT_FDCWD, path, O_SEARCH)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<long> Process::sys_fchdir(int fildes) | ||||
| 	{ | ||||
| 		LockGuard _(m_process_lock); | ||||
| 		m_working_directory = TRY(m_open_file_descriptors.file_of(fildes)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 		auto file = TRY(m_open_file_descriptors.file_of(fildes)); | ||||
| 		m_working_directory = BAN::move(file); | ||||
| 
 | ||||
| 	BAN::ErrorOr<long> Process::sys_chroot(const char* path) | ||||
| 	{ | ||||
| 		LockGuard _(m_process_lock); | ||||
| 		TRY(validate_string_access(path)); | ||||
| 		if (!m_credentials.is_superuser()) | ||||
| 			return BAN::Error::from_errno(EACCES); | ||||
| 		m_root_file = TRY(find_file(AT_FDCWD, path, O_SEARCH)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -121,8 +121,8 @@ namespace Kernel | |||
| 	void TTY::keyboard_task(void*) | ||||
| 	{ | ||||
| 		BAN::RefPtr<Inode> keyboard_inode; | ||||
| 		if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error()) | ||||
| 			keyboard_inode = ret.value().inode; | ||||
| 		if (auto ret = DevFileSystem::get().root_inode()->find_inode("keyboard"_sv); !ret.is_error()) | ||||
| 			keyboard_inode = ret.release_value(); | ||||
| 		else | ||||
| 		{ | ||||
| 			dprintln("could not open keyboard device: {}", ret.error()); | ||||
|  |  | |||
|  | @ -113,6 +113,7 @@ __BEGIN_DECLS | |||
| 	O(SYS_FUTEX,			futex)			\ | ||||
| 	O(SYS_GETGROUPS,		getgroups)		\ | ||||
| 	O(SYS_SETGROUPS,		setgroups)		\ | ||||
| 	O(SYS_CHROOT,			chroot)			\ | ||||
| 
 | ||||
| enum Syscall | ||||
| { | ||||
|  |  | |||
|  | @ -596,6 +596,7 @@ int					unlinkat(int fd, const char* path, int flag); | |||
| int					usleep(useconds_t usec); | ||||
| ssize_t				write(int fildes, const void* buf, size_t nbyte); | ||||
| 
 | ||||
| int					chroot(const char* path); | ||||
| int					getpagesize(void); | ||||
| char*				getpass(const char* prompt); | ||||
| 
 | ||||
|  |  | |||
|  | @ -626,6 +626,11 @@ int getopt(int argc, char* const argv[], const char* optstring) | |||
| 	return '?'; | ||||
| } | ||||
| 
 | ||||
| int chroot(const char* path) | ||||
| { | ||||
| 	return syscall(SYS_CHROOT, path); | ||||
| } | ||||
| 
 | ||||
| int getpagesize(void) | ||||
| { | ||||
| 	return PAGE_SIZE; | ||||
|  |  | |||
|  | @ -31,7 +31,8 @@ namespace LibFont | |||
| 
 | ||||
| #if __is_kernel | ||||
| 		{ | ||||
| 			auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, O_RDONLY)).inode; | ||||
| 			// FIXME: This does not account for chroot
 | ||||
| 			auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, O_RDONLY)).inode; | ||||
| 			TRY(file_data.resize(inode->size())); | ||||
| 			TRY(inode->read(0, BAN::ByteSpan(file_data.span()))); | ||||
| 		} | ||||
|  |  | |||
|  | @ -128,7 +128,8 @@ namespace LibInput | |||
| 
 | ||||
| #if __is_kernel | ||||
| 		{ | ||||
| 			auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0)); | ||||
| 			// FIXME: This does not account for chroot
 | ||||
| 			auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, 0)); | ||||
| 			TRY(file_data.resize(file.inode->size())); | ||||
| 			TRY(file.inode->read(0, BAN::ByteSpan { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() })); | ||||
| 			canonical_path = file.canonical_path; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue