From: Robert Obkircher <r.obkircher@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH v2 proxmox-backup 2/2] datastore: prevent potentially unaligned FixedIndexHeader reference
Date: Tue, 30 Dec 2025 13:39:49 +0100 [thread overview]
Message-ID: <20251230124154.115442-3-r.obkircher@proxmox.com> (raw)
In-Reply-To: <20251230124154.115442-1-r.obkircher@proxmox.com>
Continue to avoid the 4 KiB stack allocation in debug builds by
adopting the approach used for the DynamicIndexHeader.
This also avoid mutation through Vec::as_ptr, which is forbidden
according to its documentation.
Signed-off-by: Robert Obkircher <r.obkircher@proxmox.com>
---
pbs-datastore/src/fixed_index.rs | 35 ++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/pbs-datastore/src/fixed_index.rs b/pbs-datastore/src/fixed_index.rs
index 6c3be2d4..7241d77f 100644
--- a/pbs-datastore/src/fixed_index.rs
+++ b/pbs-datastore/src/fixed_index.rs
@@ -29,6 +29,31 @@ pub struct FixedIndexHeader {
}
proxmox_lang::static_assert_size!(FixedIndexHeader, 4096);
+impl FixedIndexHeader {
+ /// Convenience method to allocate a zero-initialized header struct.
+ pub fn zeroed() -> Box<Self> {
+ let layout = std::alloc::Layout::new::<Self>();
+ unsafe {
+ let ptr = std::alloc::alloc_zeroed(layout) as *mut Self;
+ if ptr.is_null() {
+ std::alloc::handle_alloc_error(layout);
+ }
+ Box::from_raw(ptr)
+ }
+ }
+
+ pub fn as_bytes(&self) -> &[u8] {
+ unsafe {
+ // There can't be any uninitialized padding, because the fields
+ // take up all of the statically asserted total size.
+ std::slice::from_raw_parts(
+ self as *const Self as *const u8,
+ std::mem::size_of::<Self>(),
+ )
+ }
+ }
+}
+
// split image into fixed size chunks
pub struct FixedIndexReader {
@@ -237,7 +262,6 @@ impl Drop for FixedIndexWriter {
}
impl FixedIndexWriter {
- #[allow(clippy::cast_ptr_alignment)]
// Requires obtaining a shared chunk store lock beforehand
pub fn create(
store: Arc<ChunkStore>,
@@ -267,18 +291,13 @@ impl FixedIndexWriter {
let uuid = Uuid::generate();
- let buffer = vec![0u8; header_size];
- let header = unsafe { &mut *(buffer.as_ptr() as *mut FixedIndexHeader) };
-
+ let mut header = FixedIndexHeader::zeroed();
header.magic = file_formats::FIXED_SIZED_CHUNK_INDEX_1_0;
header.ctime = i64::to_le(ctime);
header.size = u64::to_le(size as u64);
header.chunk_size = u64::to_le(chunk_size as u64);
header.uuid = *uuid.as_bytes();
-
- header.index_csum = [0u8; 32];
-
- file.write_all(&buffer)?;
+ file.write_all(header.as_bytes())?;
let index_length = size.div_ceil(chunk_size);
let index_size = index_length * 32;
--
2.47.3
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
prev parent reply other threads:[~2025-12-30 12:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-30 12:39 [pbs-devel] [PATCH v2 proxmox-backup 0/2] " Robert Obkircher
2025-12-30 12:39 ` [pbs-devel] [PATCH v2 proxmox-backup 1/2] datastore: check for null pointer when allocating DynamicIndexHeader Robert Obkircher
2026-01-07 13:10 ` Christian Ebner
2026-01-07 14:29 ` Robert Obkircher
2026-01-07 14:57 ` Christian Ebner
2025-12-30 12:39 ` Robert Obkircher [this message]
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=20251230124154.115442-3-r.obkircher@proxmox.com \
--to=r.obkircher@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox