commit ced0bc2172d4cd5169e3514997db069a813077b7
parent d3c2429255e99d42bf10b6cf3fe6f6a3c5debdb6
Author: Sertonix <sertonix@posteo.net>
Date: Mon, 30 Oct 2023 18:00:54 +0000
io: bounds check readv/writev
Abort if the amount of vectors would be truncated.
Diffstat:
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/io/+freebsd/vector.ha b/io/+freebsd/vector.ha
@@ -3,6 +3,7 @@
use errors;
use rt;
+use types;
export type vector = rt::iovec;
@@ -16,6 +17,7 @@ export fn mkvector(buf: []u8) vector = vector {
// the vectors, prepared with [[mkvector]], in order, and the total number of
// bytes read is returned.
export fn readv(fd: file, vectors: vector...) (size | EOF | error) = {
+ assert(len(vectors) <= types::INT_MAX: size);
match (rt::readv(fd, vectors: *[*]rt::iovec, len(vectors): int)) {
case let err: rt::errno =>
return errors::errno(err);
@@ -33,6 +35,7 @@ export fn readv(fd: file, vectors: vector...) (size | EOF | error) = {
// with [[mkvector]], are written to the file in order, and the total number of
// bytes written is returned.
export fn writev(fd: file, vectors: vector...) (size | error) = {
+ assert(len(vectors) <= types::INT_MAX: size);
match (rt::writev(fd, vectors: *[*]rt::iovec, len(vectors): int)) {
case let err: rt::errno =>
return errors::errno(err);
diff --git a/io/+linux/vector.ha b/io/+linux/vector.ha
@@ -3,6 +3,7 @@
use errors;
use rt;
+use types;
export type vector = rt::iovec;
@@ -16,6 +17,7 @@ export fn mkvector(buf: []u8) vector = vector {
// the vectors, prepared with [[mkvector]], in order, and the total number of
// bytes read is returned.
export fn readv(fd: file, vectors: vector...) (size | EOF | error) = {
+ assert(len(vectors) <= types::INT_MAX: size);
match (rt::readv(fd, vectors: *[*]rt::iovec, len(vectors): int)) {
case let err: rt::errno =>
return errors::errno(err);
@@ -33,6 +35,7 @@ export fn readv(fd: file, vectors: vector...) (size | EOF | error) = {
// with [[mkvector]], are written to the file in order, and the total number of
// bytes written is returned.
export fn writev(fd: file, vectors: vector...) (size | error) = {
+ assert(len(vectors) <= types::INT_MAX: size);
match (rt::writev(fd, vectors: *[*]rt::iovec, len(vectors): int)) {
case let err: rt::errno =>
return errors::errno(err);