Kernel: Move file finding code to a helper
This commit is contained in:
		
							parent
							
								
									a6b973003b
								
							
						
					
					
						commit
						b779b3cf2d
					
				| 
						 | 
					@ -213,6 +213,8 @@ namespace Kernel
 | 
				
			||||||
		Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
 | 
							Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
 | 
				
			||||||
		static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
 | 
							static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<void> validate_string_access(const char*);
 | 
							BAN::ErrorOr<void> validate_string_access(const char*);
 | 
				
			||||||
		BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
 | 
							BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
 | 
				
			||||||
		BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
 | 
							BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -351,6 +351,28 @@ namespace Kernel
 | 
				
			||||||
		return read_from_vec_of_str(m_environ, offset, buffer);
 | 
							return read_from_vec_of_str(m_environ, offset, buffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<VirtualFileSystem::File> Process::find_file(int fd, const char* path, int flags)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ASSERT(m_process_lock.is_locked());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (path)
 | 
				
			||||||
 | 
								TRY(validate_string_access(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VirtualFileSystem::File parent_file;
 | 
				
			||||||
 | 
							if (path && path[0] == '/')
 | 
				
			||||||
 | 
								parent_file = VirtualFileSystem::get().root_file();
 | 
				
			||||||
 | 
							else if (fd == AT_FDCWD)
 | 
				
			||||||
 | 
								parent_file = TRY(m_working_directory.clone());
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								parent_file = TRY(m_open_file_descriptors.file_of(fd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto file = path
 | 
				
			||||||
 | 
								? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
 | 
				
			||||||
 | 
								: BAN::move(parent_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return file;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<long> Process::sys_exit(int status)
 | 
						BAN::ErrorOr<long> Process::sys_exit(int status)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(this == &Process::current());
 | 
							ASSERT(this == &Process::current());
 | 
				
			||||||
| 
						 | 
					@ -1000,15 +1022,7 @@ namespace Kernel
 | 
				
			||||||
		TRY(validate_string_access(path));
 | 
							TRY(validate_string_access(path));
 | 
				
			||||||
		TRY(validate_pointer_access(buffer, bufsize, true));
 | 
							TRY(validate_pointer_access(buffer, bufsize, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VirtualFileSystem::File parent_file;
 | 
							auto inode = TRY(find_file(fd, path, O_NOFOLLOW | O_RDONLY)).inode;
 | 
				
			||||||
		if (path[0] == '/')
 | 
					 | 
				
			||||||
			parent_file = VirtualFileSystem::get().root_file();
 | 
					 | 
				
			||||||
		else if (fd == AT_FDCWD)
 | 
					 | 
				
			||||||
			parent_file = TRY(m_working_directory.clone());
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			parent_file = TRY(m_open_file_descriptors.file_of(fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY)).inode;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// FIXME: no allocation needed
 | 
							// FIXME: no allocation needed
 | 
				
			||||||
		auto link_target = TRY(inode->link_target());
 | 
							auto link_target = TRY(inode->link_target());
 | 
				
			||||||
| 
						 | 
					@ -1036,20 +1050,8 @@ namespace Kernel
 | 
				
			||||||
			flag = O_NOFOLLOW;
 | 
								flag = O_NOFOLLOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		LockGuard _(m_process_lock);
 | 
							LockGuard _(m_process_lock);
 | 
				
			||||||
		if (path)
 | 
					 | 
				
			||||||
			TRY(validate_string_access(path));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VirtualFileSystem::File parent_file;
 | 
							auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
 | 
				
			||||||
		if (path && path[0] == '/')
 | 
					 | 
				
			||||||
			parent_file = VirtualFileSystem::get().root_file();
 | 
					 | 
				
			||||||
		else if (fd == AT_FDCWD)
 | 
					 | 
				
			||||||
			parent_file = TRY(m_working_directory.clone());
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			parent_file = TRY(m_open_file_descriptors.file_of(fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto inode = path
 | 
					 | 
				
			||||||
			? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flag)).inode
 | 
					 | 
				
			||||||
			: parent_file.inode;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
 | 
							if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -1070,20 +1072,8 @@ namespace Kernel
 | 
				
			||||||
			flag = O_NOFOLLOW;
 | 
								flag = O_NOFOLLOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		LockGuard _(m_process_lock);
 | 
							LockGuard _(m_process_lock);
 | 
				
			||||||
		if (path)
 | 
					 | 
				
			||||||
			TRY(validate_string_access(path));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VirtualFileSystem::File parent_file;
 | 
							auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
 | 
				
			||||||
		if (path && path[0] == '/')
 | 
					 | 
				
			||||||
			parent_file = VirtualFileSystem::get().root_file();
 | 
					 | 
				
			||||||
		else if (fd == AT_FDCWD)
 | 
					 | 
				
			||||||
			parent_file = TRY(m_working_directory.clone());
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			parent_file = TRY(m_open_file_descriptors.file_of(fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto inode = path
 | 
					 | 
				
			||||||
			? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flag)).inode
 | 
					 | 
				
			||||||
			: parent_file.inode;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (uid != -1 && !m_credentials.is_superuser())
 | 
							if (uid != -1 && !m_credentials.is_superuser())
 | 
				
			||||||
			return BAN::Error::from_errno(EPERM);
 | 
								return BAN::Error::from_errno(EPERM);
 | 
				
			||||||
| 
						 | 
					@ -1425,29 +1415,17 @@ namespace Kernel
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flags)
 | 
						BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flag)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (flags & ~AT_SYMLINK_NOFOLLOW)
 | 
							if (flag & ~AT_SYMLINK_NOFOLLOW)
 | 
				
			||||||
			return BAN::Error::from_errno(EINVAL);
 | 
								return BAN::Error::from_errno(EINVAL);
 | 
				
			||||||
		if (flags == AT_SYMLINK_NOFOLLOW)
 | 
							if (flag == AT_SYMLINK_NOFOLLOW)
 | 
				
			||||||
			flags = O_NOFOLLOW;
 | 
								flag = O_NOFOLLOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		LockGuard _(m_process_lock);
 | 
							LockGuard _(m_process_lock);
 | 
				
			||||||
		if (path)
 | 
					 | 
				
			||||||
			TRY(validate_string_access(path));
 | 
					 | 
				
			||||||
		TRY(validate_pointer_access(buf, sizeof(struct stat), true));
 | 
							TRY(validate_pointer_access(buf, sizeof(struct stat), true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VirtualFileSystem::File parent_file;
 | 
							auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
 | 
				
			||||||
		if (path && path[0] == '/')
 | 
					 | 
				
			||||||
			parent_file = VirtualFileSystem::get().root_file();
 | 
					 | 
				
			||||||
		else if (fd == AT_FDCWD)
 | 
					 | 
				
			||||||
			parent_file = TRY(m_working_directory.clone());
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			parent_file = TRY(m_open_file_descriptors.file_of(fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const auto inode = path
 | 
					 | 
				
			||||||
			? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode
 | 
					 | 
				
			||||||
			: parent_file.inode;
 | 
					 | 
				
			||||||
		buf->st_dev		= inode->dev();
 | 
							buf->st_dev		= inode->dev();
 | 
				
			||||||
		buf->st_ino		= inode->ino();
 | 
							buf->st_ino		= inode->ino();
 | 
				
			||||||
		buf->st_mode	= inode->mode().mode;
 | 
							buf->st_mode	= inode->mode().mode;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue