Skip to content

Commit e4c4536

Browse files
author
carpentry-heartbeat[bot]
committed
Fix send_nb_ negative offset UB and send_len_ OOB read
- Add offset < 0 guard to send_nb_ to prevent pointer arithmetic underflow on negative offset values - Add len bounds check to send_len_ to reject negative len or len exceeding the string length (returns -1/error) - Update send-len doc to state the precondition - Add tests for send-nb with non-zero and negative offset
1 parent aaf845d commit e4c4536

3 files changed

Lines changed: 13 additions & 3 deletions

File tree

src/unix_stream.carp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@
7373
(Fn [&UnixStream &String Int] Int)
7474
"UnixStream_send_MINUS_len_")
7575

76-
(doc send-len
77-
"sends a string with known length (avoids strlen). Returns bytes sent or an error.")
76+
(doc send-len "sends a string with known length (avoids strlen). `len` must be
77+
between 0 and the string’s length; returns an error otherwise.
78+
Returns bytes sent or an error.")
7879
(defn send-len [stream msg len]
7980
(let [n (send-len- stream msg len)]
8081
(if (= n -1) (Result.Error (System.error-text)) (Result.Success n))))

src/unix_stream.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,12 @@ void UnixStream_set_MINUS_nonblocking(UnixStream* s) {
110110
}
111111

112112
int UnixStream_send_MINUS_len_(UnixStream* s, String* msg, int len) {
113+
if (len < 0 || len > (int)strlen(*msg)) return -1;
113114
return (int)send_all(s->fd, *msg, (size_t)len);
114115
}
115116

116117
int UnixStream_send_MINUS_nb_(UnixStream* s, Array* data, int offset) {
117-
if (offset >= data->len) return 0;
118+
if (offset < 0 || offset >= data->len) return 0;
118119
ssize_t n = send(s->fd, (char*)data->data + offset,
119120
(size_t)(data->len - offset), 0);
120121
if (n >= 0) return (int)n;

test/unix_test.carp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@
6868
(match (UnixStream.send-nb &client &payload 0)
6969
(Result.Success n) (when (/= n 2) (set! ok false))
7070
(Result.Error _) (set! ok false))
71+
; send-nb with offset skips leading bytes
72+
(match (UnixStream.send-nb &client &payload 1)
73+
(Result.Success n) (when (/= n 1) (set! ok false))
74+
(Result.Error _) (set! ok false))
75+
; send-nb with negative offset returns 0 (guard)
76+
(match (UnixStream.send-nb &client &payload -1)
77+
(Result.Success n) (when (/= n 0) (set! ok false))
78+
(Result.Error _) (set! ok false))
7179
(UnixStream.close client)
7280
(UnixStream.close conn)
7381
(UnixListener.close listener)

0 commit comments

Comments
 (0)