From: "Max R. Carrara" <m.carrara@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox-backup v3 7/9] tape: blocked_{reader,writer}: remove haphazard `unsafe` blocks
Date: Wed, 9 Sep 2026 17:40:21 +0200 [thread overview]
Message-ID: <20260909154027.595374-8-m.carrara@proxmox.com> (raw)
In-Reply-To: <20260909154027.595374-1-m.carrara@proxmox.com>
Both the `BlockedReader<R>` and `BlockedWriter<W>` structs use private
helpers that cast their `TapeBlock` to a (mutable) byte slice using an
`unsafe` block for reading and writing a tape block, respectively.
Neither `unsafe` block is prefixed with a "// SAFETY: ..." comment,
nor should these casts be done inline in the first place.
Instead, implement these casts as methods on `TapeBlock` directly,
with either `unsafe` block being preceded with a SAFETY comment.
Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
pbs-tape/src/blocked_reader.rs | 9 +--------
pbs-tape/src/blocked_writer.rs | 8 +-------
pbs-tape/src/tape_block.rs | 25 +++++++++++++++++++++++++
3 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/pbs-tape/src/blocked_reader.rs b/pbs-tape/src/blocked_reader.rs
index 6b1e3c692..6f5f87aa7 100644
--- a/pbs-tape/src/blocked_reader.rs
+++ b/pbs-tape/src/blocked_reader.rs
@@ -95,14 +95,7 @@ impl<R: BlockRead> BlockedReader<R> {
}
fn read_block_frame(tape_block: &mut TapeBlock, reader: &mut R) -> Result<(), BlockReadError> {
- let data = unsafe {
- std::slice::from_raw_parts_mut(
- (tape_block as *mut TapeBlock) as *mut u8,
- TapeBlock::SIZE,
- )
- };
-
- let bytes = reader.read_block(data)?;
+ let bytes = reader.read_block(tape_block.as_bytes_mut())?;
if bytes != TapeBlock::SIZE {
return Err(proxmox_lang::io_format_err!("got wrong block size").into());
diff --git a/pbs-tape/src/blocked_writer.rs b/pbs-tape/src/blocked_writer.rs
index 0d5d10147..44ff15ae0 100644
--- a/pbs-tape/src/blocked_writer.rs
+++ b/pbs-tape/src/blocked_writer.rs
@@ -46,13 +46,7 @@ impl<W: BlockWrite> BlockedWriter<W> {
}
fn write_block(tape_block: &TapeBlock, writer: &mut W) -> Result<bool, std::io::Error> {
- let data = unsafe {
- std::slice::from_raw_parts(
- (tape_block as *const TapeBlock) as *const u8,
- TapeBlock::SIZE,
- )
- };
- writer.write_block(data)
+ writer.write_block(tape_block.as_bytes())
}
fn write_eof(&mut self) -> Result<(), std::io::Error> {
diff --git a/pbs-tape/src/tape_block.rs b/pbs-tape/src/tape_block.rs
index 730f7d9dc..00377c3ad 100644
--- a/pbs-tape/src/tape_block.rs
+++ b/pbs-tape/src/tape_block.rs
@@ -117,4 +117,29 @@ impl TapeBlock {
pub fn payload_mut(&mut self) -> &mut [u8] {
&mut self.payload
}
+
+ /// Returns the entirety of the tape block, meaning both its header and data
+ /// payload, as a byte slice.
+ pub fn as_bytes(&self) -> &[u8] {
+ // SAFETY:
+ // - Our memory is always zero-initialized.
+ // - We do not use interior mutability.
+ // - The resulting slice never outlives `self`.
+ unsafe { std::slice::from_raw_parts(core::ptr::from_ref(self).cast(), size_of_val(self)) }
+ }
+
+ /// Returns the entirety of the tape block, meaning both its header and data
+ /// payload, as a mutable byte slice.
+ ///
+ /// While this method in itself is safe, be aware that it nevertheless
+ /// allows you to overwrite the tape block's header fields.
+ pub fn as_bytes_mut(&mut self) -> &mut [u8] {
+ // SAFETY:
+ // - Since we uniquely borrow `self`, we may cast `self` to a `* mut`
+ // and use it to acquire a mutable slice.
+ // - Our memory is always zero-initialized.
+ // - We do not use interior mutability.
+ // - The resulting slice never outlives `self`.
+ unsafe { std::slice::from_raw_parts_mut(core::ptr::from_mut(self).cast(), size_of_val(self)) }
+ }
}
--
2.47.3
next prev parent reply other threads:[~2026-09-09 15:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 15:40 [PATCH proxmox{,-backup} v3 0/9] Fix Undefined Behavior in Tape Block Header Deallocation Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox v3 1/9] proxmox-alloc: introduce proxmox-alloc with `LayoutAwareBox<T>` type Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 2/9] tape: move tape block structs into separate file module Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 3/9] tape: rename `BlockHeader` and `BlockHeaderFlags` Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 4/9] tape: blocked_{reader,writer}: rename `buffer` to `tape_block` Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 5/9] tape: tape block: represent tape block header with its own struct Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 6/9] tape: tape block: make `payload` field private Max R. Carrara
2026-09-09 15:40 ` Max R. Carrara [this message]
2026-09-09 15:40 ` [PATCH proxmox-backup v3 8/9] tape: tape block: fix undefined behavior on tape block deallocation Max R. Carrara
2026-09-09 15:40 ` [PATCH proxmox-backup v3 9/9] tape: sgutils2: fix undefined behavior in dealloc of buffer Max R. Carrara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909154027.595374-8-m.carrara@proxmox.com \
--to=m.carrara@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.