Kernel: Clean up file creation
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user