Compare commits
3 Commits
51820b15cb
...
3ad6fdfa39
Author | SHA1 | Date |
---|---|---|
Bananymous | 3ad6fdfa39 | |
Bananymous | 96d831c31a | |
Bananymous | 07d5d3f936 |
|
@ -66,6 +66,7 @@ namespace BAN
|
|||
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
|
||||
IteratorSimpleGeneral(const IteratorSimpleGeneral<T, Container, CONST2>& other)
|
||||
: m_pointer(other.m_pointer)
|
||||
, m_valid(other.m_valid)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,24 +78,28 @@ namespace BAN
|
|||
template<bool CONST2 = CONST>
|
||||
enable_if_t<!CONST2, T&> operator*()
|
||||
{
|
||||
ASSERT(*this);
|
||||
ASSERT(m_pointer);
|
||||
return *m_pointer;
|
||||
}
|
||||
|
||||
const T* operator->() const
|
||||
{
|
||||
ASSERT(*this);
|
||||
ASSERT(m_pointer);
|
||||
return m_pointer;
|
||||
}
|
||||
template<bool CONST2 = CONST>
|
||||
enable_if_t<!CONST2, T*> operator->()
|
||||
{
|
||||
ASSERT(*this);
|
||||
ASSERT(m_pointer);
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
IteratorSimpleGeneral& operator++()
|
||||
{
|
||||
ASSERT(*this);
|
||||
ASSERT(m_pointer);
|
||||
++m_pointer;
|
||||
return *this;
|
||||
|
@ -108,6 +113,7 @@ namespace BAN
|
|||
|
||||
IteratorSimpleGeneral& operator--()
|
||||
{
|
||||
ASSERT(*this);
|
||||
ASSERT(m_pointer);
|
||||
--m_pointer;
|
||||
return *this;
|
||||
|
@ -121,7 +127,7 @@ namespace BAN
|
|||
|
||||
size_t operator-(const IteratorSimpleGeneral& other) const
|
||||
{
|
||||
ASSERT(m_pointer);
|
||||
ASSERT(*this && other);
|
||||
return m_pointer - other.m_pointer;
|
||||
}
|
||||
|
||||
|
@ -137,31 +143,36 @@ namespace BAN
|
|||
|
||||
bool operator<(const IteratorSimpleGeneral& other) const
|
||||
{
|
||||
ASSERT(*this);
|
||||
return m_pointer < other.m_pointer;
|
||||
}
|
||||
|
||||
bool operator==(const IteratorSimpleGeneral& other) const
|
||||
{
|
||||
ASSERT(*this);
|
||||
return m_pointer == other.m_pointer;
|
||||
}
|
||||
bool operator!=(const IteratorSimpleGeneral& other) const
|
||||
{
|
||||
ASSERT(*this);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return m_pointer;
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
IteratorSimpleGeneral(maybe_const_t<CONST, T>* pointer)
|
||||
: m_pointer(pointer)
|
||||
, m_valid(true)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
maybe_const_t<CONST, T>* m_pointer = nullptr;
|
||||
bool m_valid = false;
|
||||
|
||||
friend IteratorSimpleGeneral<T, Container, !CONST>;
|
||||
friend Container;
|
||||
|
@ -239,14 +250,14 @@ namespace BAN
|
|||
|
||||
bool operator==(const IteratorDoubleGeneral& other) const
|
||||
{
|
||||
if (!*this || !other)
|
||||
return false;
|
||||
ASSERT(*this && other);
|
||||
if (m_outer_end != other.m_outer_end)
|
||||
return false;
|
||||
if (m_outer_current != other.m_outer_current)
|
||||
return false;
|
||||
if (m_outer_current == m_outer_end)
|
||||
return true;
|
||||
ASSERT(m_inner_current && other.m_inner_current);
|
||||
return m_inner_current == other.m_inner_current;
|
||||
}
|
||||
bool operator!=(const IteratorDoubleGeneral& other) const
|
||||
|
@ -256,7 +267,7 @@ namespace BAN
|
|||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return m_outer_end && m_outer_current;
|
||||
return !!m_outer_current;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
Binary file not shown.
|
@ -14,6 +14,7 @@ set(KERNEL_SOURCES
|
|||
kernel/APIC.cpp
|
||||
kernel/BootInfo.cpp
|
||||
kernel/CPUID.cpp
|
||||
kernel/Credentials.cpp
|
||||
kernel/Debug.cpp
|
||||
kernel/Device/Device.cpp
|
||||
kernel/Device/FramebufferDevice.cpp
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/Vector.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace Kernel
|
||||
|
@ -31,9 +33,17 @@ namespace Kernel
|
|||
|
||||
bool is_superuser() const { return m_euid == 0; }
|
||||
|
||||
bool has_egid(gid_t) const;
|
||||
|
||||
BAN::ErrorOr<void> initialize_supplementary_groups();
|
||||
|
||||
private:
|
||||
BAN::ErrorOr<BAN::String> find_username() const;
|
||||
|
||||
private:
|
||||
uid_t m_ruid, m_euid, m_suid;
|
||||
gid_t m_rgid, m_egid, m_sgid;
|
||||
BAN::Vector<gid_t> m_supplementary;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<size_t> write(off_t, BAN::ConstByteSpan buffer);
|
||||
BAN::ErrorOr<void> truncate(size_t);
|
||||
BAN::ErrorOr<void> chmod(mode_t);
|
||||
BAN::ErrorOr<void> chown(uid_t, gid_t);
|
||||
bool has_data() const;
|
||||
|
||||
protected:
|
||||
|
@ -119,6 +120,7 @@ namespace Kernel
|
|||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual BAN::ErrorOr<void> truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual BAN::ErrorOr<void> chmod_impl(mode_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -108,6 +108,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_pread(int fd, void* buffer, size_t count, off_t offset);
|
||||
|
||||
BAN::ErrorOr<long> sys_chmod(const char*, mode_t);
|
||||
BAN::ErrorOr<long> sys_chown(const char*, uid_t, gid_t);
|
||||
|
||||
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
||||
BAN::ErrorOr<long> sys_dup(int fildes);
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace Kernel
|
|||
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
|
||||
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) override;
|
||||
|
||||
virtual bool has_data_impl() const override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
#include <kernel/Credentials.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
static id_t parse_id(BAN::StringView line)
|
||||
{
|
||||
id_t id = 0;
|
||||
for (char c : line)
|
||||
{
|
||||
if (!isdigit(c))
|
||||
return -1;
|
||||
id = (id * 10) + (c - '0');
|
||||
}
|
||||
return id;
|
||||
};
|
||||
|
||||
BAN::ErrorOr<BAN::String> Credentials::find_username() const
|
||||
{
|
||||
auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path(*this, "/etc/passwd"sv, O_RDONLY)).inode;
|
||||
|
||||
BAN::String line;
|
||||
off_t offset = 0;
|
||||
uint8_t buffer[128];
|
||||
while (offset < inode->size())
|
||||
{
|
||||
size_t nread = TRY(inode->read(offset, { buffer, sizeof(buffer) }));
|
||||
|
||||
bool line_done = false;
|
||||
for (size_t i = 0; i < nread; i++)
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
TRY(line.append({ (const char*)buffer, i }));
|
||||
line_done = true;
|
||||
offset += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!line_done)
|
||||
{
|
||||
offset += nread;
|
||||
TRY(line.append({ (const char*)buffer, nread }));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto parts = TRY(line.sv().split(':', true));
|
||||
if (parts.size() == 7 && m_euid == parse_id(parts[2]))
|
||||
{
|
||||
BAN::String result;
|
||||
TRY(result.append(parts[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
line.clear();
|
||||
}
|
||||
|
||||
auto parts = TRY(line.sv().split(':', true));
|
||||
if (parts.size() == 7 && m_euid == parse_id(parts[2]))
|
||||
{
|
||||
BAN::String result;
|
||||
TRY(result.append(parts[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Credentials::initialize_supplementary_groups()
|
||||
{
|
||||
m_supplementary.clear();
|
||||
|
||||
auto username = TRY(find_username());
|
||||
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path(*this, "/etc/group", O_RDONLY);
|
||||
if (file_or_error.is_error())
|
||||
{
|
||||
if (file_or_error.error().get_error_code() == ENOENT)
|
||||
return {};
|
||||
return file_or_error.error();
|
||||
}
|
||||
|
||||
auto inode = file_or_error.value().inode;
|
||||
|
||||
BAN::String line;
|
||||
off_t offset = 0;
|
||||
uint8_t buffer[128];
|
||||
while (offset < inode->size())
|
||||
{
|
||||
size_t nread = TRY(inode->read(offset, { buffer, sizeof(buffer) }));
|
||||
|
||||
bool line_done = false;
|
||||
for (size_t i = 0; i < nread; i++)
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
TRY(line.append({ (const char*)buffer, i }));
|
||||
line_done = true;
|
||||
offset += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!line_done)
|
||||
{
|
||||
offset += nread;
|
||||
TRY(line.append({ (const char*)buffer, nread }));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto parts = TRY(line.sv().split(':', true));
|
||||
if (parts.size() != 4)
|
||||
{
|
||||
line.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto users = TRY(parts[3].split(','));
|
||||
for (auto user : users)
|
||||
{
|
||||
if (user != username)
|
||||
continue;
|
||||
if (gid_t gid = parse_id(parts[2]); gid != -1)
|
||||
{
|
||||
TRY(m_supplementary.push_back(gid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line.clear();
|
||||
}
|
||||
|
||||
auto parts = TRY(line.sv().split(':', true));
|
||||
if (parts.size() == 4)
|
||||
{
|
||||
auto users = TRY(parts[3].split(','));
|
||||
for (auto user : users)
|
||||
{
|
||||
if (user != username)
|
||||
continue;
|
||||
if (gid_t gid = parse_id(parts[2]); gid != -1)
|
||||
{
|
||||
TRY(m_supplementary.push_back(gid));
|
||||
dprintln(" {}", parts[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Credentials::has_egid(gid_t gid) const
|
||||
{
|
||||
if (m_egid == gid)
|
||||
return true;
|
||||
for (gid_t supplementary : m_supplementary)
|
||||
if (gid == supplementary)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace Kernel
|
|||
if (g_boot_info.framebuffer.bpp != 24 && g_boot_info.framebuffer.bpp != 32)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
auto* device_ptr = new FramebufferDevice(
|
||||
0666, 0, 0,
|
||||
0660, 0, 900,
|
||||
DevFileSystem::get().get_next_dev(),
|
||||
g_boot_info.framebuffer.address,
|
||||
g_boot_info.framebuffer.width,
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Kernel
|
|||
{ }
|
||||
else if ((mode().mode & S_IRUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IRGRP) && credentials.egid() == gid())
|
||||
else if ((mode().mode & S_IRGRP) && credentials.has_egid(gid()))
|
||||
{ }
|
||||
else
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace Kernel
|
|||
{ }
|
||||
else if ((mode().mode & S_IWUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IWGRP) && credentials.egid() == gid())
|
||||
else if ((mode().mode & S_IWGRP) && credentials.has_egid(gid()))
|
||||
{ }
|
||||
else
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ namespace Kernel
|
|||
{ }
|
||||
else if ((mode().mode & S_IXUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IXGRP) && credentials.egid() == gid())
|
||||
else if ((mode().mode & S_IXGRP) && credentials.has_egid(gid()))
|
||||
{ }
|
||||
else
|
||||
{
|
||||
|
@ -141,6 +141,12 @@ namespace Kernel
|
|||
return chmod_impl(mode);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::chown(uid_t uid, gid_t gid)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
return chown_impl(uid, gid);
|
||||
}
|
||||
|
||||
bool Inode::has_data() const
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace Kernel::Input
|
|||
static PS2Controller* s_instance = nullptr;
|
||||
|
||||
PS2Device::PS2Device()
|
||||
: CharacterDevice(0440, 0, 0)
|
||||
: CharacterDevice(0440, 0, 901)
|
||||
, m_name(BAN::String::formatted("input{}", DevFileSystem::get().get_next_input_device()))
|
||||
{ }
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ namespace Kernel
|
|||
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path)
|
||||
{
|
||||
auto* process = create_process(credentials, 0);
|
||||
TRY(process->m_credentials.initialize_supplementary_groups());
|
||||
|
||||
MUST(process->m_working_directory.push_back('/'));
|
||||
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
|
||||
|
||||
|
@ -886,6 +888,18 @@ namespace Kernel
|
|||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_chown(const char* path, uid_t uid, gid_t gid)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
validate_string_access(path);
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_WRONLY));
|
||||
TRY(file.inode->chown(uid, gid));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
@ -1336,6 +1350,7 @@ namespace Kernel
|
|||
m_credentials.set_euid(uid);
|
||||
m_credentials.set_ruid(uid);
|
||||
m_credentials.set_suid(uid);
|
||||
TRY(m_credentials.initialize_supplementary_groups());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1344,6 +1359,7 @@ namespace Kernel
|
|||
if (uid == m_credentials.ruid() || uid == m_credentials.suid())
|
||||
{
|
||||
m_credentials.set_euid(uid);
|
||||
TRY(m_credentials.initialize_supplementary_groups());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1390,6 +1406,7 @@ namespace Kernel
|
|||
if (uid == m_credentials.ruid() || uid == m_credentials.suid() || m_credentials.is_superuser())
|
||||
{
|
||||
m_credentials.set_euid(uid);
|
||||
TRY(m_credentials.initialize_supplementary_groups());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1456,6 +1473,8 @@ namespace Kernel
|
|||
if (euid != -1)
|
||||
m_credentials.set_euid(euid);
|
||||
|
||||
TRY(m_credentials.initialize_supplementary_groups());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,6 +211,9 @@ namespace Kernel
|
|||
case SYS_PREAD:
|
||||
ret = Process::current().sys_pread((int)arg1, (void*)arg2, (size_t)arg3, (off_t)arg4);
|
||||
break;
|
||||
case SYS_CHOWN:
|
||||
ret = Process::current().sys_chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3);
|
||||
break;
|
||||
default:
|
||||
dwarnln("Unknown syscall {}", syscall);
|
||||
break;
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace Kernel
|
|||
}
|
||||
|
||||
SerialTTY::SerialTTY(Serial serial)
|
||||
: TTY(0660, 0, 0)
|
||||
: TTY(0600, 0, 0)
|
||||
, m_serial(serial)
|
||||
, m_rdev(next_rdev())
|
||||
{
|
||||
|
|
|
@ -105,6 +105,21 @@ namespace Kernel
|
|||
initialized = true;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TTY::chmod_impl(mode_t mode)
|
||||
{
|
||||
ASSERT((mode & Inode::Mode::TYPE_MASK) == 0);
|
||||
m_inode_info.mode &= Inode::Mode::TYPE_MASK;
|
||||
m_inode_info.mode |= mode;
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TTY::chown_impl(uid_t uid, gid_t gid)
|
||||
{
|
||||
m_inode_info.uid = uid;
|
||||
m_inode_info.gid = gid;
|
||||
return {};
|
||||
}
|
||||
|
||||
void TTY::on_key_event(Input::KeyEvent event)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace Kernel
|
|||
}
|
||||
|
||||
VirtualTTY::VirtualTTY(TerminalDriver* driver)
|
||||
: TTY(0666, 0, 0)
|
||||
: TTY(0600, 0, 0)
|
||||
, m_terminal_driver(driver)
|
||||
, m_rdev(next_rdev())
|
||||
{
|
||||
|
|
|
@ -61,6 +61,7 @@ __BEGIN_DECLS
|
|||
#define SYS_READLINKAT 60
|
||||
#define SYS_MSYNC 61
|
||||
#define SYS_PREAD 62
|
||||
#define SYS_CHOWN 63
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -270,6 +270,11 @@ int chdir(const char* path)
|
|||
return syscall(SYS_SET_PWD, path);
|
||||
}
|
||||
|
||||
int chown(const char* path, uid_t owner, gid_t group)
|
||||
{
|
||||
return syscall(SYS_CHOWN, path, owner, group);
|
||||
}
|
||||
|
||||
void sync(void)
|
||||
{
|
||||
syscall(SYS_SYNC, false);
|
||||
|
|
|
@ -63,6 +63,18 @@ int main()
|
|||
if (pwd == nullptr)
|
||||
continue;
|
||||
|
||||
if (chown("/dev/tty", pwd->pw_uid, pwd->pw_gid) == -1)
|
||||
{
|
||||
perror("chown");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chmod("/dev/tty", 0600) == -1)
|
||||
{
|
||||
perror("chmod");
|
||||
continue;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue