1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-11 18:20:43 +09:00

Kernel: Make syscalls that take a buffer size use ssize_t instead of size_t.

Dealing with the unsigned overflow propagation here just seems unreasonably
error prone. Let's limit ourselves to 2GB buffer sizes instead.
This commit is contained in:
Andreas Kling 2019-02-25 21:19:57 +01:00
parent 5af4e622b9
commit beda478821
Notes: sideshowbarker 2024-07-19 15:37:56 +09:00
40 changed files with 144 additions and 136 deletions

View file

@ -132,12 +132,12 @@ bool BXVGADevice::can_write(Process&) const
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
ssize_t BXVGADevice::read(Process&, byte*, size_t) ssize_t BXVGADevice::read(Process&, byte*, ssize_t)
{ {
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
ssize_t BXVGADevice::write(Process&, const byte*, size_t) ssize_t BXVGADevice::write(Process&, const byte*, ssize_t)
{ {
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }

View file

@ -27,8 +27,8 @@ private:
virtual const char* class_name() const override { return "BXVGA"; } virtual const char* class_name() const override { return "BXVGA"; }
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override; virtual bool can_write(Process&) const override;
virtual ssize_t read(Process&, byte*, size_t) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte*, size_t) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
void set_register(word index, word value); void set_register(word index, word value);
dword find_framebuffer_address(); dword find_framebuffer_address();

View file

@ -28,20 +28,20 @@ bool Console::can_read(Process&) const
return false; return false;
} }
ssize_t Console::read(Process&, byte*, size_t) ssize_t Console::read(Process&, byte*, ssize_t)
{ {
// FIXME: Implement reading from the console. // FIXME: Implement reading from the console.
// Maybe we could use a ring buffer for this device? // Maybe we could use a ring buffer for this device?
return 0; return 0;
} }
ssize_t Console::write(Process&, const byte* data, size_t size) ssize_t Console::write(Process&, const byte* data, ssize_t size)
{ {
if (!size) if (!size)
return 0; return 0;
if (!m_implementation) if (!m_implementation)
return 0; return 0;
for (size_t i = 0; i < size; ++i) for (ssize_t i = 0; i < size; ++i)
put_char(data[i]); put_char(data[i]);
return size; return size;
} }

View file

@ -21,8 +21,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
virtual ssize_t read(Process&, byte* buffer, size_t size) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* data, size_t size) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual const char* class_name() const override { return "Console"; } virtual const char* class_name() const override { return "Console"; }
void set_implementation(ConsoleImplementation* implementation) { m_implementation = implementation; } void set_implementation(ConsoleImplementation* implementation) { m_implementation = implementation; }

View file

@ -19,8 +19,8 @@ public:
virtual bool can_read(Process&) const = 0; virtual bool can_read(Process&) const = 0;
virtual bool can_write(Process&) const = 0; virtual bool can_write(Process&) const = 0;
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) = 0; virtual ssize_t read(Process&, byte*, ssize_t) = 0;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) = 0; virtual ssize_t write(Process&, const byte*, ssize_t) = 0;
unsigned major() const { return m_major; } unsigned major() const { return m_major; }
unsigned minor() const { return m_minor; } unsigned minor() const { return m_minor; }

View file

@ -1,4 +1,4 @@
#include "DoubleBuffer.h" #include <Kernel/DoubleBuffer.h>
inline void DoubleBuffer::compute_emptiness() inline void DoubleBuffer::compute_emptiness()
{ {
@ -17,24 +17,22 @@ void DoubleBuffer::flip()
compute_emptiness(); compute_emptiness();
} }
ssize_t DoubleBuffer::write(const byte* data, size_t size) ssize_t DoubleBuffer::write(const byte* data, ssize_t size)
{ {
ASSERT_INTERRUPTS_ENABLED();
LOCKER(m_lock); LOCKER(m_lock);
m_write_buffer->append(data, size); m_write_buffer->append(data, size);
compute_emptiness(); compute_emptiness();
return size; return size;
} }
ssize_t DoubleBuffer::read(byte* data, size_t size) ssize_t DoubleBuffer::read(byte* data, ssize_t size)
{ {
ASSERT_INTERRUPTS_ENABLED();
LOCKER(m_lock); LOCKER(m_lock);
if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->is_empty()) if (m_read_buffer_index >= m_read_buffer->size() && !m_write_buffer->is_empty())
flip(); flip();
if (m_read_buffer_index >= m_read_buffer->size()) if (m_read_buffer_index >= m_read_buffer->size())
return 0; return 0;
ssize_t nread = min(m_read_buffer->size() - m_read_buffer_index, size); ssize_t nread = min((ssize_t)m_read_buffer->size() - m_read_buffer_index, size);
memcpy(data, m_read_buffer->data() + m_read_buffer_index, nread); memcpy(data, m_read_buffer->data() + m_read_buffer_index, nread);
m_read_buffer_index += nread; m_read_buffer_index += nread;
compute_emptiness(); compute_emptiness();

View file

@ -13,13 +13,13 @@ public:
{ {
} }
ssize_t write(const byte*, size_t); ssize_t write(const byte*, ssize_t);
ssize_t read(byte*, size_t); ssize_t read(byte*, ssize_t);
bool is_empty() const { return m_empty; } bool is_empty() const { return m_empty; }
// FIXME: Isn't this racy? What if we get interrupted between getting the buffer pointer and dereferencing it? // FIXME: Isn't this racy? What if we get interrupted between getting the buffer pointer and dereferencing it?
size_t bytes_in_write_buffer() const { return m_write_buffer->size(); } ssize_t bytes_in_write_buffer() const { return (ssize_t)m_write_buffer->size(); }
private: private:
void flip(); void flip();
@ -29,7 +29,7 @@ private:
Vector<byte>* m_read_buffer { nullptr }; Vector<byte>* m_read_buffer { nullptr };
Vector<byte> m_buffer1; Vector<byte> m_buffer1;
Vector<byte> m_buffer2; Vector<byte> m_buffer2;
size_t m_read_buffer_index { 0 }; ssize_t m_read_buffer_index { 0 };
bool m_empty { true }; bool m_empty { true };
Lock m_lock; Lock m_lock;
}; };

View file

@ -54,21 +54,21 @@ bool FIFO::can_write() const
return m_buffer.bytes_in_write_buffer() < 4096; return m_buffer.bytes_in_write_buffer() < 4096;
} }
ssize_t FIFO::read(byte* buffer, size_t size) ssize_t FIFO::read(byte* buffer, ssize_t size)
{ {
if (!m_writers && m_buffer.is_empty()) if (!m_writers && m_buffer.is_empty())
return 0; return 0;
#ifdef FIFO_DEBUG #ifdef FIFO_DEBUG
dbgprintf("fifo: read(%u)\n",size); dbgprintf("fifo: read(%u)\n",size);
#endif #endif
size_t nread = m_buffer.read(buffer, size); ssize_t nread = m_buffer.read(buffer, size);
#ifdef FIFO_DEBUG #ifdef FIFO_DEBUG
dbgprintf(" -> read (%c) %u\n", buffer[0], nread); dbgprintf(" -> read (%c) %u\n", buffer[0], nread);
#endif #endif
return nread; return nread;
} }
ssize_t FIFO::write(const byte* buffer, size_t size) ssize_t FIFO::write(const byte* buffer, ssize_t size)
{ {
if (!m_readers) if (!m_readers)
return 0; return 0;

View file

@ -16,8 +16,8 @@ public:
void open(Direction); void open(Direction);
void close(Direction); void close(Direction);
ssize_t write(const byte*, size_t); ssize_t write(const byte*, ssize_t);
ssize_t read(byte*, size_t); ssize_t read(byte*, ssize_t);
bool can_read() const; bool can_read() const;
bool can_write() const; bool can_write() const;

View file

@ -176,7 +176,7 @@ off_t FileDescriptor::seek(off_t offset, int whence)
return m_current_offset; return m_current_offset;
} }
ssize_t FileDescriptor::read(Process& process, byte* buffer, size_t count) ssize_t FileDescriptor::read(Process& process, byte* buffer, ssize_t count)
{ {
if (is_fifo()) { if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Reader); ASSERT(fifo_direction() == FIFO::Reader);
@ -194,7 +194,7 @@ ssize_t FileDescriptor::read(Process& process, byte* buffer, size_t count)
return nread; return nread;
} }
ssize_t FileDescriptor::write(Process& process, const byte* data, size_t size) ssize_t FileDescriptor::write(Process& process, const byte* data, ssize_t size)
{ {
if (is_fifo()) { if (is_fifo()) {
ASSERT(fifo_direction() == FIFO::Writer); ASSERT(fifo_direction() == FIFO::Writer);
@ -245,6 +245,7 @@ ByteBuffer FileDescriptor::read_entire_file(Process& process)
if (m_device) { if (m_device) {
auto buffer = ByteBuffer::create_uninitialized(1024); auto buffer = ByteBuffer::create_uninitialized(1024);
ssize_t nread = m_device->read(process, buffer.pointer(), buffer.size()); ssize_t nread = m_device->read(process, buffer.pointer(), buffer.size());
ASSERT(nread >= 0);
buffer.trim(nread); buffer.trim(nread);
return buffer; return buffer;
} }
@ -259,7 +260,7 @@ bool FileDescriptor::is_directory() const
return metadata().is_directory(); return metadata().is_directory();
} }
ssize_t FileDescriptor::get_dir_entries(byte* buffer, size_t size) ssize_t FileDescriptor::get_dir_entries(byte* buffer, ssize_t size)
{ {
auto metadata = this->metadata(); auto metadata = this->metadata();
if (!metadata.is_valid()) if (!metadata.is_valid())

View file

@ -30,14 +30,14 @@ public:
int close(); int close();
off_t seek(off_t, int whence); off_t seek(off_t, int whence);
ssize_t read(Process&, byte*, size_t); ssize_t read(Process&, byte*, ssize_t);
ssize_t write(Process&, const byte* data, size_t); ssize_t write(Process&, const byte* data, ssize_t);
int fstat(stat*); int fstat(stat*);
bool can_read(Process&); bool can_read(Process&);
bool can_write(Process&); bool can_write(Process&);
ssize_t get_dir_entries(byte* buffer, size_t); ssize_t get_dir_entries(byte* buffer, ssize_t);
ByteBuffer read_entire_file(Process&); ByteBuffer read_entire_file(Process&);

View file

@ -18,16 +18,16 @@ bool FullDevice::can_read(Process&) const
return true; return true;
} }
ssize_t FullDevice::read(Process&, byte* buffer, size_t bufferSize) ssize_t FullDevice::read(Process&, byte* buffer, ssize_t size)
{ {
size_t count = min(GoodBufferSize, bufferSize); ssize_t count = min(GoodBufferSize, size);
memset(buffer, 0, count); memset(buffer, 0, (size_t)count);
return count; return count;
} }
ssize_t FullDevice::write(Process&, const byte*, size_t bufferSize) ssize_t FullDevice::write(Process&, const byte*, ssize_t size)
{ {
if (bufferSize == 0) if (size == 0)
return 0; return 0;
return -ENOSPC; return -ENOSPC;
} }

View file

@ -10,8 +10,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
virtual const char* class_name() const override { return "FullDevice"; } virtual const char* class_name() const override { return "FullDevice"; }

View file

@ -177,14 +177,14 @@ bool KeyboardDevice::can_read(Process&) const
return !m_queue.is_empty(); return !m_queue.is_empty();
} }
ssize_t KeyboardDevice::read(Process&, byte* buffer, size_t size) ssize_t KeyboardDevice::read(Process&, byte* buffer, ssize_t size)
{ {
ssize_t nread = 0; ssize_t nread = 0;
while ((size_t)nread < size) { while (nread < size) {
if (m_queue.is_empty()) if (m_queue.is_empty())
break; break;
// Don't return partial data frames. // Don't return partial data frames.
if ((size - nread) < sizeof(Event)) if ((size - nread) < (ssize_t)sizeof(Event))
break; break;
auto event = m_queue.dequeue(); auto event = m_queue.dequeue();
memcpy(buffer, &event, sizeof(Event)); memcpy(buffer, &event, sizeof(Event));
@ -193,7 +193,7 @@ ssize_t KeyboardDevice::read(Process&, byte* buffer, size_t size)
return nread; return nread;
} }
ssize_t KeyboardDevice::write(Process&, const byte*, size_t) ssize_t KeyboardDevice::write(Process&, const byte*, ssize_t)
{ {
return 0; return 0;
} }

View file

@ -22,9 +22,9 @@ public:
void set_client(KeyboardClient* client) { m_client = client; } void set_client(KeyboardClient* client) { m_client = client; }
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte* buffer, size_t) override; virtual ssize_t read(Process&, byte* buffer, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual ssize_t write(Process&, const byte* buffer, size_t) override; virtual ssize_t write(Process&, const byte* buffer, ssize_t) override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
private: private:

View file

@ -4,6 +4,6 @@
inline static const off_t maxFileOffset = 2147483647; inline static const off_t maxFileOffset = 2147483647;
static const size_t GoodBufferSize = 4096; static const ssize_t GoodBufferSize = 4096;

View file

@ -137,7 +137,7 @@ bool LocalSocket::can_read(SocketRole role) const
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
ssize_t LocalSocket::read(SocketRole role, byte* buffer, size_t size) ssize_t LocalSocket::read(SocketRole role, byte* buffer, ssize_t size)
{ {
if (role == SocketRole::Accepted) if (role == SocketRole::Accepted)
return m_for_server.read(buffer, size); return m_for_server.read(buffer, size);
@ -146,7 +146,7 @@ ssize_t LocalSocket::read(SocketRole role, byte* buffer, size_t size)
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
ssize_t LocalSocket::write(SocketRole role, const byte* data, size_t size) ssize_t LocalSocket::write(SocketRole role, const byte* data, ssize_t size)
{ {
if (role == SocketRole::Accepted) { if (role == SocketRole::Accepted) {
if (!m_accepted_fds_open) if (!m_accepted_fds_open)

View file

@ -16,8 +16,8 @@ public:
virtual void attach_fd(SocketRole) override; virtual void attach_fd(SocketRole) override;
virtual void detach_fd(SocketRole) override; virtual void detach_fd(SocketRole) override;
virtual bool can_read(SocketRole) const override; virtual bool can_read(SocketRole) const override;
virtual ssize_t read(SocketRole, byte*, size_t) override; virtual ssize_t read(SocketRole, byte*, ssize_t) override;
virtual ssize_t write(SocketRole, const byte*, size_t) override; virtual ssize_t write(SocketRole, const byte*, ssize_t) override;
virtual bool can_write(SocketRole) const override; virtual bool can_write(SocketRole) const override;
private: private:

View file

@ -26,14 +26,14 @@ String MasterPTY::pts_name() const
return String::format("/dev/pts/%u", m_index); return String::format("/dev/pts/%u", m_index);
} }
ssize_t MasterPTY::read(Process&, byte* buffer, size_t size) ssize_t MasterPTY::read(Process&, byte* buffer, ssize_t size)
{ {
if (!m_slave && m_buffer.is_empty()) if (!m_slave && m_buffer.is_empty())
return 0; return 0;
return m_buffer.read(buffer, size); return m_buffer.read(buffer, size);
} }
ssize_t MasterPTY::write(Process&, const byte* buffer, size_t size) ssize_t MasterPTY::write(Process&, const byte* buffer, ssize_t size)
{ {
if (!m_slave) if (!m_slave)
return -EIO; return -EIO;
@ -62,7 +62,7 @@ void MasterPTY::notify_slave_closed(Badge<SlavePTY>)
m_slave = nullptr; m_slave = nullptr;
} }
ssize_t MasterPTY::on_slave_write(const byte* data, size_t size) ssize_t MasterPTY::on_slave_write(const byte* data, ssize_t size)
{ {
if (m_closed) if (m_closed)
return -EIO; return -EIO;

View file

@ -13,15 +13,15 @@ public:
unsigned index() const { return m_index; } unsigned index() const { return m_index; }
String pts_name() const; String pts_name() const;
ssize_t on_slave_write(const byte*, size_t); ssize_t on_slave_write(const byte*, ssize_t);
bool can_write_from_slave() const; bool can_write_from_slave() const;
void notify_slave_closed(Badge<SlavePTY>); void notify_slave_closed(Badge<SlavePTY>);
bool is_closed() const { return m_closed; } bool is_closed() const { return m_closed; }
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte*, size_t) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte*, size_t) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override; virtual bool can_write(Process&) const override;
virtual void close() override; virtual void close() override;

View file

@ -815,6 +815,8 @@ void VMObject::inode_size_changed(Badge<Inode>, size_t old_size, size_t new_size
void VMObject::inode_contents_changed(Badge<Inode>, off_t offset, size_t size, const byte* data) void VMObject::inode_contents_changed(Badge<Inode>, off_t offset, size_t size, const byte* data)
{ {
(void)size;
(void)data;
InterruptDisabler disabler; InterruptDisabler disabler;
ASSERT(offset >= 0); ASSERT(offset >= 0);

View file

@ -26,13 +26,13 @@ bool NullDevice::can_read(Process&) const
return true; return true;
} }
ssize_t NullDevice::read(Process&, byte*, size_t) ssize_t NullDevice::read(Process&, byte*, ssize_t)
{ {
return 0; return 0;
} }
ssize_t NullDevice::write(Process&, const byte*, size_t bufferSize) ssize_t NullDevice::write(Process&, const byte*, ssize_t buffer_size)
{ {
return min(GoodBufferSize, bufferSize); return min(GoodBufferSize, buffer_size);
} }

View file

@ -12,8 +12,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual const char* class_name() const override { return "NullDevice"; } virtual const char* class_name() const override { return "NullDevice"; }

View file

@ -144,10 +144,10 @@ bool PS2MouseDevice::can_read(Process&) const
return !m_queue.is_empty(); return !m_queue.is_empty();
} }
ssize_t PS2MouseDevice::read(Process&, byte* buffer, size_t size) ssize_t PS2MouseDevice::read(Process&, byte* buffer, ssize_t size)
{ {
ssize_t nread = 0; ssize_t nread = 0;
while ((size_t)nread < size) { while (nread < size) {
if (m_queue.is_empty()) if (m_queue.is_empty())
break; break;
// FIXME: Don't return partial data frames. // FIXME: Don't return partial data frames.
@ -156,7 +156,7 @@ ssize_t PS2MouseDevice::read(Process&, byte* buffer, size_t size)
return nread; return nread;
} }
ssize_t PS2MouseDevice::write(Process&, const byte*, size_t) ssize_t PS2MouseDevice::write(Process&, const byte*, ssize_t)
{ {
return 0; return 0;
} }

View file

@ -12,8 +12,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual ssize_t read(Process&, byte* buffer, size_t) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* buffer, size_t) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
private: private:

View file

@ -16,8 +16,8 @@ public:
// ^CharacterDevice // ^CharacterDevice
virtual RetainPtr<FileDescriptor> open(int& error, int options) override; virtual RetainPtr<FileDescriptor> open(int& error, int options) override;
virtual ssize_t read(Process&, byte*, size_t) override { return 0; } virtual ssize_t read(Process&, byte*, ssize_t) override { return 0; }
virtual ssize_t write(Process&, const byte*, size_t) override { return 0; } virtual ssize_t write(Process&, const byte*, ssize_t) override { return 0; }
virtual bool can_read(Process&) const override { return true; } virtual bool can_read(Process&) const override { return true; }
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }

View file

@ -199,8 +199,10 @@ int Process::sys$munmap(void* addr, size_t size)
return 0; return 0;
} }
int Process::sys$gethostname(char* buffer, size_t size) int Process::sys$gethostname(char* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
LOCKER(*s_hostname_lock); LOCKER(*s_hostname_lock);
@ -971,8 +973,10 @@ const FileDescriptor* Process::file_descriptor(int fd) const
return nullptr; return nullptr;
} }
ssize_t Process::sys$get_dir_entries(int fd, void* buffer, size_t size) ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
auto* descriptor = file_descriptor(fd); auto* descriptor = file_descriptor(fd);
@ -989,8 +993,10 @@ int Process::sys$lseek(int fd, off_t offset, int whence)
return descriptor->seek(offset, whence); return descriptor->seek(offset, whence);
} }
int Process::sys$ttyname_r(int fd, char* buffer, size_t size) int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
auto* descriptor = file_descriptor(fd); auto* descriptor = file_descriptor(fd);
@ -1005,8 +1011,10 @@ int Process::sys$ttyname_r(int fd, char* buffer, size_t size)
return 0; return 0;
} }
int Process::sys$ptsname_r(int fd, char* buffer, size_t size) int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
auto* descriptor = file_descriptor(fd); auto* descriptor = file_descriptor(fd);
@ -1022,8 +1030,10 @@ int Process::sys$ptsname_r(int fd, char* buffer, size_t size)
return 0; return 0;
} }
ssize_t Process::sys$write(int fd, const void* data, size_t size) ssize_t Process::sys$write(int fd, const byte* data, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_read(data, size)) if (!validate_read(data, size))
return -EFAULT; return -EFAULT;
#ifdef DEBUG_IO #ifdef DEBUG_IO
@ -1074,26 +1084,21 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
if (nwritten == 0) if (nwritten == 0)
return -EINTR; return -EINTR;
} }
#ifdef DEBUG_IO
dbgprintf("%s(%u) sys$write: nwritten=%u\n", name().characters(), pid(), nwritten);
#endif
return nwritten; return nwritten;
} }
ssize_t Process::sys$read(int fd, void* outbuf, size_t nread) ssize_t Process::sys$read(int fd, byte* buffer, ssize_t size)
{ {
if (!validate_write(outbuf, nread)) if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
#ifdef DEBUG_IO #ifdef DEBUG_IO
dbgprintf("%s(%u) sys$read(%d, %p, %u)\n", name().characters(), pid(), fd, outbuf, nread); dbgprintf("%s(%u) sys$read(%d, %p, %u)\n", name().characters(), pid(), fd, buffer, size);
#endif #endif
auto* descriptor = file_descriptor(fd); auto* descriptor = file_descriptor(fd);
if (!descriptor) if (!descriptor)
return -EBADF; return -EBADF;
#ifdef DEBUG_IO
dbgprintf(" > descriptor:%p, is_blocking:%u, can_read:%u\n", descriptor, descriptor->is_blocking(), descriptor->can_read(*this));
dbgprintf(" > inode:K%x, device:K%x\n", descriptor->inode(), descriptor->character_device());
#endif
if (descriptor->is_blocking()) { if (descriptor->is_blocking()) {
if (!descriptor->can_read(*this)) { if (!descriptor->can_read(*this)) {
m_blocked_fd = fd; m_blocked_fd = fd;
@ -1103,11 +1108,7 @@ ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
return -EINTR; return -EINTR;
} }
} }
nread = descriptor->read(*this, (byte*)outbuf, nread); return descriptor->read(*this, buffer, size);
#ifdef DEBUG_IO
dbgprintf("%s(%u) Process::sys$read: nread=%u\n", name().characters(), pid(), nread);
#endif
return nread;
} }
int Process::sys$close(int fd) int Process::sys$close(int fd)
@ -1221,8 +1222,10 @@ int Process::sys$stat(const char* path, stat* statbuf)
return 0; return 0;
} }
int Process::sys$readlink(const char* path, char* buffer, size_t size) int Process::sys$readlink(const char* path, char* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_read_str(path)) if (!validate_read_str(path))
return -EFAULT; return -EFAULT;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
@ -1240,7 +1243,7 @@ int Process::sys$readlink(const char* path, char* buffer, size_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.
memcpy(buffer, contents.pointer(), min(size, contents.size())); memcpy(buffer, contents.pointer(), min(size, (ssize_t)contents.size()));
if (contents.size() + 1 < size) if (contents.size() + 1 < size)
buffer[contents.size()] = '\0'; buffer[contents.size()] = '\0';
return 0; return 0;
@ -1260,8 +1263,10 @@ int Process::sys$chdir(const char* path)
return 0; return 0;
} }
int Process::sys$getcwd(char* buffer, size_t size) int Process::sys$getcwd(char* buffer, ssize_t size)
{ {
if (size < 0)
return -EINVAL;
if (!validate_write(buffer, size)) if (!validate_write(buffer, size))
return -EFAULT; return -EFAULT;
auto path = VFS::the().absolute_path(cwd_inode()); auto path = VFS::the().absolute_path(cwd_inode());
@ -1655,8 +1660,9 @@ bool Process::validate_read_str(const char* str)
return validate_read(str, strlen(str) + 1); return validate_read(str, strlen(str) + 1);
} }
bool Process::validate_read(const void* address, size_t size) const bool Process::validate_read(const void* address, ssize_t size) const
{ {
ASSERT(size >= 0);
LinearAddress first_address((dword)address); LinearAddress first_address((dword)address);
LinearAddress last_address = first_address.offset(size - 1); LinearAddress last_address = first_address.offset(size - 1);
if (is_ring0()) { if (is_ring0()) {
@ -1678,8 +1684,9 @@ bool Process::validate_read(const void* address, size_t size) const
return MM.validate_user_read(*this, first_address); return MM.validate_user_read(*this, first_address);
} }
bool Process::validate_write(void* address, size_t size) const bool Process::validate_write(void* address, ssize_t size) const
{ {
ASSERT(size >= 0);
LinearAddress first_address((dword)address); LinearAddress first_address((dword)address);
LinearAddress last_address = first_address.offset(size - 1); LinearAddress last_address = first_address.offset(size - 1);
if (is_ring0()) { if (is_ring0()) {

View file

@ -162,8 +162,8 @@ public:
mode_t sys$umask(mode_t); mode_t sys$umask(mode_t);
int sys$open(const char* path, int options, mode_t mode = 0); int sys$open(const char* path, int options, mode_t mode = 0);
int sys$close(int fd); int sys$close(int fd);
ssize_t sys$read(int fd, void* outbuf, size_t nread); ssize_t sys$read(int fd, byte*, ssize_t);
ssize_t sys$write(int fd, const void*, size_t); ssize_t sys$write(int fd, const byte*, ssize_t);
int sys$fstat(int fd, stat*); int sys$fstat(int fd, stat*);
int sys$lstat(const char*, stat*); int sys$lstat(const char*, stat*);
int sys$stat(const char*, stat*); int sys$stat(const char*, stat*);
@ -178,17 +178,17 @@ public:
int sys$set_mmap_name(void*, size_t, const char*); int sys$set_mmap_name(void*, size_t, const char*);
int sys$select(const Syscall::SC_select_params*); int sys$select(const Syscall::SC_select_params*);
int sys$poll(pollfd*, int nfds, int timeout); int sys$poll(pollfd*, int nfds, int timeout);
ssize_t sys$get_dir_entries(int fd, void*, size_t); ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
int sys$getcwd(char*, size_t); int sys$getcwd(char*, ssize_t);
int sys$chdir(const char*); int sys$chdir(const char*);
int sys$sleep(unsigned seconds); int sys$sleep(unsigned seconds);
int sys$usleep(useconds_t usec); int sys$usleep(useconds_t usec);
int sys$gettimeofday(timeval*); int sys$gettimeofday(timeval*);
int sys$gethostname(char* name, size_t length); int sys$gethostname(char*, ssize_t);
int sys$uname(utsname*); int sys$uname(utsname*);
int sys$readlink(const char*, char*, size_t); int sys$readlink(const char*, char*, ssize_t);
int sys$ttyname_r(int fd, char*, size_t); int sys$ttyname_r(int fd, char*, ssize_t);
int sys$ptsname_r(int fd, char*, size_t); int sys$ptsname_r(int fd, char*, ssize_t);
pid_t sys$fork(RegisterDump&); pid_t sys$fork(RegisterDump&);
int sys$execve(const char* filename, const char** argv, const char** envp); int sys$execve(const char* filename, const char** argv, const char** envp);
int sys$isatty(int fd); int sys$isatty(int fd);
@ -257,8 +257,8 @@ public:
bool validate_read_from_kernel(LinearAddress) const; bool validate_read_from_kernel(LinearAddress) const;
bool validate_read(const void*, size_t) const; bool validate_read(const void*, ssize_t) const;
bool validate_write(void*, size_t) const; bool validate_write(void*, ssize_t) const;
bool validate_read_str(const char* str); bool validate_read_str(const char* str);
template<typename T> bool validate_read_typed(T* value, size_t count = 1) { return validate_read(value, sizeof(T) * count); } template<typename T> bool validate_read_typed(T* value, size_t count = 1) { return validate_read(value, sizeof(T) * count); }
template<typename T> bool validate_write_typed(T* value, size_t count = 1) { return validate_write(value, sizeof(T) * count); } template<typename T> bool validate_write_typed(T* value, size_t count = 1) { return validate_write(value, sizeof(T) * count); }

View file

@ -34,20 +34,20 @@ bool RandomDevice::can_read(Process&) const
return true; return true;
} }
ssize_t RandomDevice::read(Process&, byte* buffer, size_t bufferSize) ssize_t RandomDevice::read(Process&, byte* buffer, ssize_t size)
{ {
const int range = 'z' - 'a'; const int range = 'z' - 'a';
ssize_t nread = min(bufferSize, GoodBufferSize); ssize_t nread = min(size, GoodBufferSize);
for (ssize_t i = 0; i < nread; ++i) { for (ssize_t i = 0; i < nread; ++i) {
dword r = myrand() % range; dword r = myrand() % range;
buffer[i] = 'a' + r; buffer[i] = (byte)('a' + r);
} }
return nread; return nread;
} }
ssize_t RandomDevice::write(Process&, const byte*, size_t bufferSize) ssize_t RandomDevice::write(Process&, const byte*, ssize_t size)
{ {
// FIXME: Use input for entropy? I guess that could be a neat feature? // FIXME: Use input for entropy? I guess that could be a neat feature?
return min(GoodBufferSize, bufferSize); return min(GoodBufferSize, size);
} }

View file

@ -10,8 +10,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
virtual const char* class_name() const override { return "RandomDevice"; } virtual const char* class_name() const override { return "RandomDevice"; }

View file

@ -25,13 +25,13 @@ String SlavePTY::tty_name() const
return String::format("/dev/pts/%u", m_index); return String::format("/dev/pts/%u", m_index);
} }
void SlavePTY::on_master_write(const byte* buffer, size_t size) void SlavePTY::on_master_write(const byte* buffer, ssize_t size)
{ {
for (size_t i = 0; i < size; ++i) for (ssize_t i = 0; i < size; ++i)
emit(buffer[i]); emit(buffer[i]);
} }
ssize_t SlavePTY::on_tty_write(const byte* data, size_t size) ssize_t SlavePTY::on_tty_write(const byte* data, ssize_t size)
{ {
return m_master->on_slave_write(data, size); return m_master->on_slave_write(data, size);
} }
@ -48,7 +48,7 @@ bool SlavePTY::can_read(Process& process) const
return TTY::can_read(process); return TTY::can_read(process);
} }
ssize_t SlavePTY::read(Process& process, byte* buffer, size_t size) ssize_t SlavePTY::read(Process& process, byte* buffer, ssize_t size)
{ {
if (m_master->is_closed()) if (m_master->is_closed())
return 0; return 0;

View file

@ -8,7 +8,7 @@ class SlavePTY final : public TTY {
public: public:
virtual ~SlavePTY() override; virtual ~SlavePTY() override;
void on_master_write(const byte*, size_t); void on_master_write(const byte*, ssize_t);
unsigned index() const { return m_index; } unsigned index() const { return m_index; }
InodeIdentifier devpts_inode_id() const { return m_devpts_inode_id; } InodeIdentifier devpts_inode_id() const { return m_devpts_inode_id; }
@ -17,11 +17,11 @@ public:
private: private:
// ^TTY // ^TTY
virtual String tty_name() const override; virtual String tty_name() const override;
virtual ssize_t on_tty_write(const byte*, size_t) override; virtual ssize_t on_tty_write(const byte*, ssize_t) override;
// ^CharacterDevice // ^CharacterDevice
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual ssize_t read(Process&, byte*, size_t) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual bool can_write(Process&) const override; virtual bool can_write(Process&) const override;
virtual const char* class_name() const override { return "SlavePTY"; } virtual const char* class_name() const override { return "SlavePTY"; }
virtual void close() override; virtual void close() override;

View file

@ -30,8 +30,8 @@ public:
virtual void attach_fd(SocketRole) = 0; virtual void attach_fd(SocketRole) = 0;
virtual void detach_fd(SocketRole) = 0; virtual void detach_fd(SocketRole) = 0;
virtual bool can_read(SocketRole) const = 0; virtual bool can_read(SocketRole) const = 0;
virtual ssize_t read(SocketRole, byte*, size_t) = 0; virtual ssize_t read(SocketRole, byte*, ssize_t) = 0;
virtual ssize_t write(SocketRole, const byte*, size_t) = 0; virtual ssize_t write(SocketRole, const byte*, ssize_t) = 0;
virtual bool can_write(SocketRole) const = 0; virtual bool can_write(SocketRole) const = 0;
pid_t origin_pid() const { return m_origin_pid; } pid_t origin_pid() const { return m_origin_pid; }

View file

@ -77,11 +77,11 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
case Syscall::SC_open: case Syscall::SC_open:
return current->sys$open((const char*)arg1, (int)arg2, (mode_t)arg3); return current->sys$open((const char*)arg1, (int)arg2, (mode_t)arg3);
case Syscall::SC_write: case Syscall::SC_write:
return current->sys$write((int)arg1, (const void*)arg2, (size_t)arg3); return current->sys$write((int)arg1, (const byte*)arg2, (ssize_t)arg3);
case Syscall::SC_close: case Syscall::SC_close:
return current->sys$close((int)arg1); return current->sys$close((int)arg1);
case Syscall::SC_read: case Syscall::SC_read:
return current->sys$read((int)arg1, (void*)arg2, (size_t)arg3); return current->sys$read((int)arg1, (byte*)arg2, (ssize_t)arg3);
case Syscall::SC_lseek: case Syscall::SC_lseek:
return current->sys$lseek((int)arg1, (off_t)arg2, (int)arg3); return current->sys$lseek((int)arg1, (off_t)arg2, (int)arg3);
case Syscall::SC_kill: case Syscall::SC_kill:

View file

@ -24,12 +24,12 @@ void TTY::set_default_termios()
memcpy(m_termios.c_cc, default_cc, sizeof(default_cc)); memcpy(m_termios.c_cc, default_cc, sizeof(default_cc));
} }
ssize_t TTY::read(Process&, byte* buffer, size_t size) ssize_t TTY::read(Process&, byte* buffer, ssize_t size)
{ {
return m_buffer.read(buffer, size); return m_buffer.read(buffer, size);
} }
ssize_t TTY::write(Process&, const byte* buffer, size_t size) ssize_t TTY::write(Process&, const byte* buffer, ssize_t size)
{ {
#ifdef TTY_DEBUG #ifdef TTY_DEBUG
dbgprintf("TTY::write {%u} ", size); dbgprintf("TTY::write {%u} ", size);

View file

@ -10,8 +10,8 @@ class TTY : public CharacterDevice {
public: public:
virtual ~TTY() override; virtual ~TTY() override;
virtual ssize_t read(Process&, byte*, size_t) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte*, size_t) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override; virtual bool can_write(Process&) const override;
virtual int ioctl(Process&, unsigned request, unsigned arg) override final; virtual int ioctl(Process&, unsigned request, unsigned arg) override final;
@ -33,7 +33,7 @@ public:
void hang_up(); void hang_up();
protected: protected:
virtual ssize_t on_tty_write(const byte*, size_t) = 0; virtual ssize_t on_tty_write(const byte*, ssize_t) = 0;
void set_size(unsigned short columns, unsigned short rows); void set_size(unsigned short columns, unsigned short rows);
TTY(unsigned major, unsigned minor); TTY(unsigned major, unsigned minor);

View file

@ -499,10 +499,10 @@ void VirtualConsole::on_sysconsole_receive(byte ch)
m_current_attribute = old_attribute; m_current_attribute = old_attribute;
} }
ssize_t VirtualConsole::on_tty_write(const byte* data, size_t size) ssize_t VirtualConsole::on_tty_write(const byte* data, ssize_t size)
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
for (size_t i = 0; i < size; ++i) for (ssize_t i = 0; i < size; ++i)
on_char(data[i]); on_char(data[i]);
return size; return size;
} }

View file

@ -23,7 +23,7 @@ private:
virtual void on_sysconsole_receive(byte) override; virtual void on_sysconsole_receive(byte) override;
// ^TTY // ^TTY
virtual ssize_t on_tty_write(const byte*, size_t) override; virtual ssize_t on_tty_write(const byte*, ssize_t) override;
virtual String tty_name() const override; virtual String tty_name() const override;
// ^CharacterDevice // ^CharacterDevice

View file

@ -17,15 +17,15 @@ bool ZeroDevice::can_read(Process&) const
return true; return true;
} }
ssize_t ZeroDevice::read(Process&, byte* buffer, size_t bufferSize) ssize_t ZeroDevice::read(Process&, byte* buffer, ssize_t size)
{ {
size_t count = min(GoodBufferSize, bufferSize); ssize_t count = min(GoodBufferSize, size);
memset(buffer, 0, count); memset(buffer, 0, (size_t)count);
return count; return count;
} }
ssize_t ZeroDevice::write(Process&, const byte*, size_t bufferSize) ssize_t ZeroDevice::write(Process&, const byte*, ssize_t size)
{ {
return min(GoodBufferSize, bufferSize); return min(GoodBufferSize, size);
} }

View file

@ -10,8 +10,8 @@ public:
private: private:
// ^CharacterDevice // ^CharacterDevice
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override; virtual ssize_t read(Process&, byte*, ssize_t) override;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) override; virtual ssize_t write(Process&, const byte*, ssize_t) override;
virtual bool can_read(Process&) const override; virtual bool can_read(Process&) const override;
virtual bool can_write(Process&) const override { return true; } virtual bool can_write(Process&) const override { return true; }
virtual const char* class_name() const override { return "ZeroDevice"; } virtual const char* class_name() const override { return "ZeroDevice"; }