mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:17:36 +00:00
Kernel: Pass characters+length to readlink()
Note that I'm developing some helper types in the Syscall namespace as I go here. Once I settle on some nice types, I will convert all the other syscalls to use them as well.
This commit is contained in:
parent
5c3c2a9bac
commit
0695ff8282
4 changed files with 37 additions and 12 deletions
|
@ -1558,17 +1558,27 @@ int Process::sys$stat(const char* user_path, size_t path_length, stat* user_stat
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
|
template<typename DataType, typename SizeType>
|
||||||
|
bool Process::validate(const Syscall::MutableBufferArgument<DataType, SizeType>& buffer)
|
||||||
{
|
{
|
||||||
if (size < 0)
|
return validate_write(buffer.data, buffer.size);
|
||||||
return -EINVAL;
|
}
|
||||||
SmapDisabler disabler;
|
|
||||||
if (!validate_read_str(path))
|
int Process::sys$readlink(const Syscall::SC_readlink_params* user_params)
|
||||||
|
{
|
||||||
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!validate_write(buffer, size))
|
Syscall::SC_readlink_params params;
|
||||||
|
copy_from_user(¶ms, user_params, sizeof(params));
|
||||||
|
|
||||||
|
if (!validate(params.buffer))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
auto result = VFS::the().open(path, O_RDONLY | O_NOFOLLOW_NOERROR, 0, current_directory());
|
auto path = get_syscall_path_argument(params.path.characters, params.path.length);
|
||||||
|
if (path.is_error())
|
||||||
|
return path.error();
|
||||||
|
|
||||||
|
auto result = VFS::the().open(path.value(), O_RDONLY | O_NOFOLLOW_NOERROR, 0, current_directory());
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
return result.error();
|
return result.error();
|
||||||
auto description = result.value();
|
auto description = result.value();
|
||||||
|
@ -1580,9 +1590,10 @@ int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
|
||||||
if (!contents)
|
if (!contents)
|
||||||
return -EIO; // FIXME: Get a more detailed error from VFS.
|
return -EIO; // FIXME: Get a more detailed error from VFS.
|
||||||
|
|
||||||
copy_to_user(buffer, contents.data(), min(size, (ssize_t)contents.size()));
|
auto link_target = String::copy(contents);
|
||||||
if (contents.size() + 1 < size)
|
if (link_target.length() + 1 > params.buffer.size)
|
||||||
buffer[contents.size()] = '\0';
|
return -ENAMETOOLONG;
|
||||||
|
copy_to_user(params.buffer.data, link_target.characters(), link_target.length() + 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ public:
|
||||||
int sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params*);
|
int sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params*);
|
||||||
int sys$gethostname(char*, ssize_t);
|
int sys$gethostname(char*, ssize_t);
|
||||||
int sys$uname(utsname*);
|
int sys$uname(utsname*);
|
||||||
int sys$readlink(const char*, char*, ssize_t);
|
int sys$readlink(const Syscall::SC_readlink_params*);
|
||||||
int sys$ttyname_r(int fd, char*, ssize_t);
|
int sys$ttyname_r(int fd, char*, ssize_t);
|
||||||
int sys$ptsname_r(int fd, char*, ssize_t);
|
int sys$ptsname_r(int fd, char*, ssize_t);
|
||||||
pid_t sys$fork(RegisterDump&);
|
pid_t sys$fork(RegisterDump&);
|
||||||
|
@ -260,6 +260,8 @@ public:
|
||||||
bool validate_read_typed(T* value, size_t count = 1) { return validate_read(value, sizeof(T) * count); }
|
bool validate_read_typed(T* value, size_t count = 1) { return validate_read(value, sizeof(T) * count); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool validate_write_typed(T* value, size_t count = 1) { return validate_write(value, sizeof(T) * count); }
|
bool validate_write_typed(T* value, size_t count = 1) { return validate_write(value, sizeof(T) * count); }
|
||||||
|
template<typename DataType, typename SizeType>
|
||||||
|
bool validate(const Syscall::MutableBufferArgument<DataType, SizeType>&);
|
||||||
|
|
||||||
Custody& current_directory();
|
Custody& current_directory();
|
||||||
Custody* executable() { return m_executable.ptr(); }
|
Custody* executable() { return m_executable.ptr(); }
|
||||||
|
|
|
@ -305,6 +305,12 @@ struct SyscallString {
|
||||||
size_t length { 0 };
|
size_t length { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename DataType, typename SizeType>
|
||||||
|
struct MutableBufferArgument {
|
||||||
|
DataType* data { nullptr };
|
||||||
|
SizeType size { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
struct SyscallStringList {
|
struct SyscallStringList {
|
||||||
SyscallString* strings { nullptr };
|
SyscallString* strings { nullptr };
|
||||||
size_t length { 0 };
|
size_t length { 0 };
|
||||||
|
@ -316,6 +322,11 @@ struct SC_execve_params {
|
||||||
SyscallStringList environment;
|
SyscallStringList environment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SC_readlink_params {
|
||||||
|
SyscallString path;
|
||||||
|
MutableBufferArgument<char, size_t> buffer;
|
||||||
|
};
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
int sync();
|
int sync();
|
||||||
|
|
||||||
|
|
|
@ -326,7 +326,8 @@ int gethostname(char* buffer, size_t size)
|
||||||
|
|
||||||
ssize_t readlink(const char* path, char* buffer, size_t size)
|
ssize_t readlink(const char* path, char* buffer, size_t size)
|
||||||
{
|
{
|
||||||
int rc = syscall(SC_readlink, path, buffer, size);
|
Syscall::SC_readlink_params params { { path, strlen(path) }, { buffer, size } };
|
||||||
|
int rc = syscall(SC_readlink, ¶ms);
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue