[PATCH] Fix UAF in IO::Buffer#& when self or mask is an invalidated slice
[PATCH] Fix UAF in IO::Buffer#| when self or mask is an invalidated slice
`io_buffer_or` accessed `buffer->base` and `mask_buffer->base` directly without validating that the buffers were still live. A slice whose parent had been freed retained its stale base pointer, so calling `|` on it caused a UAF.
Use `io_buffer_get_bytes_for_reading` for both operands, which raises `IO::Buffer::InvalidatedError` before any memory access if either buffer has been invalidated.
[PATCH] Fix UAF in IO::Buffer#^ when self or mask is an invalidated slice
`io_buffer_xor` accessed `buffer->base` and `mask_buffer->base` directly without validating that the buffers were still live. A slice whose parent had been freed retained its stale base pointer, so calling `^` on it caused a UAF.
Use `io_buffer_get_bytes_for_reading` for both operands, which raises `IO::Buffer::InvalidatedError` before any memory access if either buffer has been invalidated.
[PATCH] Fix UAF in IO::Buffer#~ when self is an invalidated slice
`io_buffer_not` accessed `buffer->base` directly without validating that the buffer was still live. A slice whose parent had been freed retained its stale base pointer, so calling `~` on it caused a UAF.
Use `io_buffer_get_bytes_for_reading`, which raises `IO::Buffer::InvalidatedError` before any memory access if the buffer has been invalidated.
[PATCH] IO::Buffer: Validate the mask argument of bit operations
[PATCH] IO::Buffer: Validate the buffer after argument conversion
[PATCH] IO::Buffer: Validate the buffer after type argument conversion
[PATCH] IO::Buffer#locked: Release lock even when the block raises (#16180)
IO::Buffer#locked: Release lock even when the block raises/breaks
Previously, `IO::Buffer#locked` leaks the lock when the block raises
an exception, or breaks.
Fixes: [Bug #21882]
[PATCH] Rename to `struct rbimpl_size_overflow_tag`
This struct is used for addition not only for multiplication, so
remove the word `mul`, and make the member names more descriptive.
The allocated buffers may be consecutive memory addresses. This will mean
that `b->base == a->base + a->size` even though `a` and `b` are separate
buffers.
Use PR_SET_VMA_ANON_NAME to set human-readable names for anonymous
virtual memory areas mapped by `mmap()` when compiled and run on Linux
5.17 or higher. This makes it convenient for developers to debug mmap.
The current implementation of `IO::Buffer#copy` and `#set_string` has
an undefined behavior when the source and destination memory overlaps,
due to the underlying use of the `memcpy` C function.
This patch guarantees the methods to be safe even when copying between
overlapping buffers by replacing `memcpy` with `memmove`,
Fixes: [Bug #20745]
This does not change any actual behaviour, but provides a choke point for blocking IO operations.
* Update `IO::Buffer` to use `rb_io_blocking_region`.
* Update `File` to use `rb_io_blocking_region`.
* Update `IO` to use `rb_io_blocking_region`.
* Restore experimental warnings.
* Documentation and code structure improvements.
* Improved validation of flags, clarified documentation of argument handling.
* Remove inconsistent use of `Example:` and add example to `null?`.
* Expose `IO::Buffer#private?` and add test.
* Fix `io_buffer_get_string` default length computation.
When an offset bigger than the size is given, the resulting length will be
computed incorrectly. Raise an argument error in this case.
* Validate all arguments.
* Documentation consistency.
* Improve consistency of `pread`/`pwrite` implementation when given length.
* Remove HAVE_PREAD / HAVE_PWRITE - it is no longer optional.
`#resize(0)` on an IO::Buffer with internal buffer allocated will
result in calling `realloc(data->base, 0)`. The behavior of `realloc`
with size = 0 is implementation-defined (glibc frees the object
and returns NULL, while BSDs return an inaccessible object). And
thus such usage is deprecated in standard C (upcoming C23 will make it
UB).
To avoid this problem, just `free`s the memory when the new size is zero.
`length` is a required argument for `IO::Buffer#read` and
`IO::Buffer#write` methods, and `argc` is already checked with
`rb_check_arity`. Also fix the call-seq of `IO::Buffer#read`.