Skip to content

Commit

Permalink
Fix possible use-after-free coming from ‘zmq-message-content’.
Browse files Browse the repository at this point in the history
‘zmq-message-content’ returns a bytevector that aliases the memory
containing message contents.  However, until now, the corresponding
<zmq-message> record could be GC’d; if user code had kept a reference to
the bytevector, said bytevector would now refer to memory that has been
freed and potentially reused—a use-after-free bug.

This commit fixes that by ensuring that the <zmq-message> record cannot
be GC’d before the bytevector itself has been GC’d.

* simple-zmq.scm.in (%message-content-table): New variable.
(zmq-message-content): Populate it.
  • Loading branch information
civodul authored and jerry40 committed Sep 30, 2023
1 parent c7d9d13 commit d25d186
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion simple-zmq.scm.in
Expand Up @@ -602,12 +602,23 @@ finalizer when the returned message goes out of scope."
(define (zmq-message-size message)
(zmq_msg_size (message->pointer message)))

(define %message-content-table
;; Map <zmq-message> records to bytevectors aliasing their contents.
(make-weak-value-hash-table))

(define (zmq-message-content message)
(let ((content-ptr (zmq_msg_data (message->pointer message)))
(size (zmq-message-size message)))
(if (null-pointer? content-ptr)
(zmq-get-error-msg "Function zmq-message-content failed.")
(pointer->bytevector content-ptr size))))
(or (hashq-ref %message-content-table message)
(let ((bv (pointer->bytevector content-ptr size)))
;; Since BV aliases memory owned by MESSAGE, ensure MESSAGE
;; remains live as long as BV is live (calling 'zmq_msg_close'
;; on MESSAGE while BV is still in use would lead to
;; use-after-free).
(hashq-set! %message-content-table message bv)
bv)))))

(define (zmq-message-gets message property)
(let-values (((result errno)
Expand Down

0 comments on commit d25d186

Please sign in to comment.