Kernel: Clean up file creation

This commit is contained in:
2026-05-18 15:26:59 +03:00
parent 5cf658c175
commit 6d1ecc2388
3 changed files with 20 additions and 24 deletions

View File

@@ -100,8 +100,8 @@ namespace Kernel
BAN::ErrorOr<long> open_inode(VirtualFileSystem::File&&, int flags); BAN::ErrorOr<long> open_inode(VirtualFileSystem::File&&, int flags);
BAN::ErrorOr<void> create_file_or_dir(int fd, const char* path, mode_t mode) const; BAN::ErrorOr<void> create_file(int fd, const char* path, mode_t) const;
BAN::ErrorOr<long> sys_openat(int, const char* path, int, mode_t); BAN::ErrorOr<long> sys_openat(int fd, const char* path, int flags, mode_t);
BAN::ErrorOr<long> sys_close(int fd); BAN::ErrorOr<long> sys_close(int fd);
BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count); BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count);
BAN::ErrorOr<long> sys_write(int fd, const void* buffer, size_t count); BAN::ErrorOr<long> sys_write(int fd, const void* buffer, size_t count);

View File

@@ -31,8 +31,10 @@ namespace Kernel
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
size_t length = 0; size_t length = 0;
while (length < address_len - sizeof(sa_family_t) && sockaddr_un.sun_path[length]) while (length < sizeof(sockaddr_un::sun_path) && sockaddr_un.sun_path[length])
length++; length++;
if (length >= sizeof(sockaddr_un::sun_path))
return BAN::Error::from_errno(ENAMETOOLONG);
return BAN::StringView { sockaddr_un.sun_path, length }; return BAN::StringView { sockaddr_un.sun_path, length };
} }
@@ -269,7 +271,7 @@ namespace Kernel
auto parent_file = sun_path.front() == '/' auto parent_file = sun_path.front() == '/'
? TRY(Process::current().root_file().clone()) ? TRY(Process::current().root_file().clone())
: TRY(Process::current().working_directory().clone()); : TRY(Process::current().working_directory().clone());
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, sun_path.data(), 0755 | S_IFSOCK); ret.is_error()) if (auto ret = Process::current().create_file(AT_FDCWD, sun_path.data(), 0755 | Inode::Mode::IFSOCK); ret.is_error())
{ {
if (ret.error().get_error_code() == EEXIST) if (ret.error().get_error_code() == EEXIST)
return BAN::Error::from_errno(EADDRINUSE); return BAN::Error::from_errno(EADDRINUSE);

View File

@@ -1163,26 +1163,27 @@ namespace Kernel
} }
} }
BAN::ErrorOr<void> Process::create_file_or_dir(int fd, const char* path, mode_t mode) const BAN::ErrorOr<void> Process::create_file(int fd, const char* path, mode_t mode) const
{ {
switch (mode & Inode::Mode::TYPE_MASK) switch (mode & Inode::Mode::TYPE_MASK)
{ {
case Inode::Mode::IFREG: case Inode::Mode::IFREG:
case Inode::Mode::IFDIR:
case Inode::Mode::IFLNK: case Inode::Mode::IFLNK:
case Inode::Mode::IFIFO: case Inode::Mode::IFIFO:
case Inode::Mode::IFSOCK: case Inode::Mode::IFSOCK:
break; break;
default: default:
return BAN::Error::from_errno(ENOTSUP); ASSERT_NOT_REACHED();
} }
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_EXEC | O_WRONLY)); struct uid_gid_t { uid_t uid; gid_t gid; };
const auto [uid, gid] = ({
LockGuard _(m_process_lock);
uid_gid_t { m_credentials.euid(), m_credentials.egid() };
});
if (Inode::Mode(mode).ifdir()) auto [parent, file_name] = TRY(find_parent_file(fd, path, O_EXEC | O_WRONLY));
TRY(parent.inode->create_directory(file_name, mode, m_credentials.euid(), parent.inode->gid())); TRY(parent.inode->create_file(file_name, mode, uid, gid));
else
TRY(parent.inode->create_file(file_name, mode, m_credentials.euid(), parent.inode->gid()));
return {}; return {};
} }
@@ -1306,14 +1307,11 @@ namespace Kernel
char path[PATH_MAX]; char path[PATH_MAX];
TRY(read_string_from_user(user_path, path, PATH_MAX)); TRY(read_string_from_user(user_path, path, PATH_MAX));
uid_t uid; struct uid_gid_t { uid_t uid; gid_t gid; };
gid_t gid; const auto [uid, gid] = ({
{
LockGuard _(m_process_lock); LockGuard _(m_process_lock);
uid = m_credentials.euid(); uid_gid_t { m_credentials.euid(), m_credentials.egid() };
gid = m_credentials.egid(); });
}
auto [parent, file_name] = TRY(find_parent_file(AT_FDCWD, path, O_WRONLY)); auto [parent, file_name] = TRY(find_parent_file(AT_FDCWD, path, O_WRONLY));
TRY(parent.inode->create_directory(file_name, (mode & 0777) | Inode::Mode::IFDIR, uid, gid)); TRY(parent.inode->create_directory(file_name, (mode & 0777) | Inode::Mode::IFDIR, uid, gid));
@@ -1376,7 +1374,6 @@ namespace Kernel
if (user_path != nullptr) if (user_path != nullptr)
TRY(read_string_from_user(user_path, path, PATH_MAX)); TRY(read_string_from_user(user_path, path, PATH_MAX));
auto [parent, file_name] = TRY(find_parent_file(fd, user_path ? path : nullptr, O_WRONLY)); auto [parent, file_name] = TRY(find_parent_file(fd, user_path ? path : nullptr, O_WRONLY));
const auto inode = TRY(parent.inode->find_inode(file_name)); const auto inode = TRY(parent.inode->find_inode(file_name));
@@ -1421,10 +1418,7 @@ namespace Kernel
if (user_path2 != nullptr) if (user_path2 != nullptr)
TRY(read_string_from_user(user_path2, path2, PATH_MAX)); TRY(read_string_from_user(user_path2, path2, PATH_MAX));
if (!find_file(fd, user_path2 ? path2 : nullptr, O_NOFOLLOW).is_error()) TRY(create_file(fd, user_path2 ? path2 : nullptr, 0777 | Inode::Mode::IFLNK));
return BAN::Error::from_errno(EEXIST);
TRY(create_file_or_dir(fd, user_path2 ? path2 : nullptr, 0777 | Inode::Mode::IFLNK));
auto symlink = TRY(find_file(fd, user_path2 ? path2 : nullptr, O_NOFOLLOW)); auto symlink = TRY(find_file(fd, user_path2 ? path2 : nullptr, O_NOFOLLOW));
TRY(symlink.inode->set_link_target(path1)); TRY(symlink.inode->set_link_target(path1));