varta-watch 0.2.0

Varta observer — receives VLP frames and surfaces stalls.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
//! Ancillary-data (CMSG) walker for `SCM_CREDENTIALS` (Linux) and `SCM_CREDS`
//! (FreeBSD / DragonFly / NetBSD).
//!
//! This module concentrates **all unsafe pointer arithmetic** that walks the
//! kernel-supplied ancillary buffer produced by `recvmsg(2)`. The Linux and
//! BSD families share the same POSIX cmsg walking discipline; only the
//! `cmsg_len` integer width and the target `(level, type)` pair differ.
//! Those differences are abstracted by [`CmsgPlatform`], and the resulting
//! [`find_credential`] function is the only entry point used by
//! `super::plat::peer_pid_after_recv`.
//!
//! macOS uses `getsockopt(LOCAL_PEERTOKEN)` and does not pass through this
//! module.

#![cfg(any(
    target_os = "linux",
    target_os = "freebsd",
    target_os = "dragonfly",
    target_os = "netbsd",
    target_os = "illumos",
    target_os = "solaris",
))]

// ---------------------------------------------------------------------------
// CMSG alignment helpers
// ---------------------------------------------------------------------------

/// `CMSG_ALIGN(len)` from `<sys/socket.h>` — round `len` up to the platform's
/// natural alignment (`sizeof(size_t)` on all targets we support).
pub(super) const fn cmsg_align(len: usize) -> usize {
    // On all supported 64-bit platforms, sizeof(size_t) == sizeof(long) == 8,
    // which matches CMSG_ALIGN.  On 32-bit both are 4.
    let align = core::mem::size_of::<usize>();
    (len + align - 1) & !(align - 1)
}

// ---------------------------------------------------------------------------
// Platform abstraction
// ---------------------------------------------------------------------------

/// Per-platform parameters for the cmsg walker.
///
/// Implemented for Linux (`SCM_CREDENTIALS` / `struct ucred` /
/// `cmsg_len: usize`), the BSD family (`SCM_CREDS` / `struct cmsgcred` /
/// `cmsg_len: u32`), and illumos/Solaris (`SCM_UCRED` / opaque `ucred_t`).
///
/// # Safety
///
/// Implementors must guarantee:
///
/// - `Hdr` is `#[repr(C)]` and matches the kernel's `struct cmsghdr` layout
///   on the implementing platform. Verified by compile-time `offset_of!`
///   assertions in `super::plat`.
/// - `Cred` is the platform's credential payload type. For typed payloads
///   (Linux `struct ucred`, BSD `struct cmsgcred`) it must be `#[repr(C)]`
///   with layout verified by compile-time `offset_of!` assertions. For
///   opaque payloads (illumos `ucred_t`) it may be the unit type `()` — in
///   that case `extract_pid_uid` receives a raw pointer and delegates to
///   libc accessors rather than casting.
/// - `Msghdr` is `#[repr(C)]` and matches the kernel's `struct msghdr` layout.
/// - `cmsg_len`, `cmsg_level`, `cmsg_type` read the kernel-reported integers
///   faithfully — `cmsg_len` widened to `usize` if narrower on the platform.
/// - `msg_control` returns the `msg_control` pointer cast to `*const u8`
///   (may be null when no ancillary data was passed).
/// - `msg_controllen` returns the kernel-reported byte count widened to
///   `usize`.
/// - `TARGET_LEVEL` / `TARGET_TYPE` are the `(level, type)` pair the kernel
///   uses for credential ancillary data on this platform.
/// - `extract_pid_uid` is called only while `data` (pointing into the
///   ancillary buffer on `recv_authenticated`'s stack frame) is still live.
///   It must not store `data` past the call.
pub(super) unsafe trait CmsgPlatform {
    /// Platform's `struct cmsghdr`.
    type Hdr;
    /// Platform's credential payload type.
    ///
    /// For typed payloads this is the concrete `#[repr(C)]` struct (`Ucred`,
    /// `Cmsgcred`). For opaque payloads (illumos `ucred_t`) use `()` — the
    /// `size_of::<Self::Cred>()` minimum-size guard in `find_credential` then
    /// evaluates to zero, and the implementor's `extract_pid_uid` handles
    /// any non-empty payload via libc accessors.
    type Cred;
    /// Platform's `struct msghdr`.
    type Msghdr;
    /// `level` the kernel sets on credential cmsg (e.g. `SOL_SOCKET`).
    const TARGET_LEVEL: i32;
    /// `type` the kernel sets on credential cmsg (e.g. `SCM_CREDENTIALS`).
    const TARGET_TYPE: i32;

    fn cmsg_len(hdr: &Self::Hdr) -> usize;
    fn cmsg_level(hdr: &Self::Hdr) -> i32;
    fn cmsg_type(hdr: &Self::Hdr) -> i32;
    fn msg_control(mhdr: &Self::Msghdr) -> *const u8;
    fn msg_controllen(mhdr: &Self::Msghdr) -> usize;

    /// Extract `(pid, effective_uid)` from the credential cmsg payload.
    ///
    /// `data` points to the first byte of the cmsg payload (after the
    /// `cmsghdr`); `len` is the payload byte count as reported by
    /// `cmsg_len - cmsg_hdr_size`. The `find_credential` entry point has
    /// already verified `len >= size_of::<Self::Cred>()`.
    ///
    /// Returns `None` when extraction fails (e.g. opaque libc accessor
    /// returns an error sentinel).
    ///
    /// # Safety
    ///
    /// `data` must point to at least `len` initialised bytes inside the
    /// ancillary buffer supplied to `CmsgIter::new`. The buffer must outlive
    /// this call (it lives on `recv_authenticated`'s stack frame — the normal
    /// calling convention). `data` must not be stored past the call.
    unsafe fn extract_pid_uid(data: *const u8, len: usize) -> Option<(u32, u32)>;

    /// Aligned size of one `cmsghdr` on this platform. Used for bounds
    /// checks and for computing the payload offset within a cmsg.
    fn cmsg_hdr_size() -> usize {
        cmsg_align(core::mem::size_of::<Self::Hdr>())
    }
}

// ---------------------------------------------------------------------------
// Iterator
// ---------------------------------------------------------------------------

/// Safe iterator over the cmsg sequence in a recvmsg ancillary buffer.
///
/// Each `next()` performs the bounds checks the POSIX walking discipline
/// requires (cursor + `cmsg_hdr_size` within `controllen`; `cmsg_len`
/// within remaining bytes) before dereferencing kernel-supplied bytes.
/// Defends against adversarial / corrupt `cmsg_len` values by clamping the
/// advance to at least `cmsg_hdr_size` and saturating cursor arithmetic, so
/// iteration always terminates regardless of input.
pub(super) struct CmsgIter<'a, P: CmsgPlatform> {
    base: *const u8,
    controllen: usize,
    cursor: usize,
    _marker: core::marker::PhantomData<&'a P::Msghdr>,
}

impl<'a, P: CmsgPlatform> CmsgIter<'a, P> {
    /// Construct an iterator from a populated msghdr.
    ///
    /// # Safety
    ///
    /// - `P::msg_control(mhdr)` must point to at least `P::msg_controllen(mhdr)`
    ///   bytes of readable memory aligned to `align_of::<usize>()`.
    /// - That region must have been initialised by `recvmsg(2)` (which the
    ///   kernel populates with a sequence of `cmsghdr + padding` records up
    ///   to `controllen` bytes), or by a test/fuzz harness that fabricates
    ///   equivalent bytes.
    /// - The caller must not mutate that region for `'a`.
    pub(super) unsafe fn new(mhdr: &'a P::Msghdr) -> Self {
        let base = P::msg_control(mhdr);
        let controllen = P::msg_controllen(mhdr);
        // Defensive sanity check — kernel never produces a non-null pointer
        // with controllen==0 followed by usable bytes, but null+nonzero is a
        // logic bug worth surfacing in debug builds.
        debug_assert!(
            !base.is_null() || controllen == 0,
            "msg_control is null but msg_controllen is non-zero"
        );
        Self {
            base,
            controllen,
            cursor: 0,
            _marker: core::marker::PhantomData,
        }
    }
}

impl<'a, P: CmsgPlatform> Iterator for CmsgIter<'a, P>
where
    P::Hdr: 'a,
{
    /// `(header, payload_data_ptr)` — `payload_data_ptr` is derived from
    /// `self.base` (full-buffer provenance) so that `extract_pid_uid`
    /// implementations can safely cast it past the header size without
    /// violating Stacked Borrows.
    type Item = (&'a P::Hdr, *const u8);

    fn next(&mut self) -> Option<(&'a P::Hdr, *const u8)> {
        if self.base.is_null() {
            return None;
        }
        // Bounds: cursor + cmsg_hdr_size must fit in controllen.
        // checked_add guards against pathological cursor values; in practice
        // the saturating math at the end of this function pins cursor to a
        // reasonable range, but defending against overflow is cheap.
        let next_min = self.cursor.checked_add(P::cmsg_hdr_size())?;
        if next_min > self.controllen {
            return None;
        }
        // SAFETY:
        // - `base + cursor` is in-bounds: `cursor + cmsg_hdr_size <= controllen`
        //   and `base` is valid for `controllen` readable bytes per `new`'s
        //   SAFETY contract.
        // - Alignment: the receive path's ancillary buffer is
        //   `#[repr(align(8))]` (see `recv::AncBuf`) and `cmsg_align` ensures
        //   `cursor` is on an 8-byte boundary; the platform's `Cmsghdr` has
        //   an alignment of at most `usize` (asserted by `offset_of!` macros
        //   in `super::plat`).
        // - The pointed-to bytes are initialised cmsghdr bytes per `recvmsg(2)`
        //   semantics (or equivalent fuzz/test fabrication).
        let hdr_ptr = unsafe { self.base.add(self.cursor) } as *const P::Hdr;
        let hdr: &P::Hdr = unsafe { &*hdr_ptr };
        let len = P::cmsg_len(hdr);
        // Validate the cmsg payload fits in the remaining buffer.
        if len > self.controllen - self.cursor {
            return None;
        }
        // Derive data_ptr from self.base (full-buffer provenance) before
        // advancing the cursor. Using self.base avoids narrowing provenance
        // to sizeof(Hdr) that would occur if derived from the `hdr` reference.
        let data_ptr = unsafe { self.base.add(self.cursor + P::cmsg_hdr_size()) };
        // Advance the cursor for the next iteration. Clamp the advance to
        // at least `cmsg_hdr_size` so an adversarial `cmsg_len == 0` (or
        // anything smaller than the header itself) cannot stall the walk in
        // an infinite loop. `saturating_add` prevents `usize` overflow from
        // wrapping into a small value that could look in-bounds.
        let advance = core::cmp::max(cmsg_align(len), P::cmsg_hdr_size());
        self.cursor = self.cursor.saturating_add(advance);
        Some((hdr, data_ptr))
    }
}

// ---------------------------------------------------------------------------
// Top-level entry point
// ---------------------------------------------------------------------------

/// Walk the ancillary data of `mhdr` and return the kernel-attested
/// `(pid, effective_uid)` from the first credential cmsg whose `(level,
/// type)` matches `P::TARGET_LEVEL` / `P::TARGET_TYPE`.
///
/// Returns `None` if no credential cmsg is present, if a candidate cmsg
/// has `cmsg_len` smaller than `cmsg_hdr_size + sizeof::<P::Cred>()`, if
/// the buffer is empty / malformed, or if `P::extract_pid_uid` returns
/// `None` (e.g. an opaque libc accessor returned an error sentinel).
///
/// # Notes
///
/// Although this function is *safe* to call from Rust, soundness relies on
/// `P::msg_control(mhdr)` and `P::msg_controllen(mhdr)` describing readable
/// memory initialised by `recvmsg(2)` — the normal contract observed by
/// `super::plat::peer_pid_after_recv`. Test and fuzz harnesses that
/// fabricate a `Msghdr` from a byte slice satisfy the same contract.
pub(super) fn find_credential<P: CmsgPlatform>(mhdr: &P::Msghdr) -> Option<(u32, u32)> {
    let needed = P::cmsg_hdr_size() + core::mem::size_of::<P::Cred>();
    // SAFETY: documented by this function's contract — callers commit that
    // `mhdr` was populated by `recvmsg(2)` (or an equivalent fabricator).
    let iter = unsafe { CmsgIter::<P>::new(mhdr) };
    for (hdr, data_ptr) in iter {
        if P::cmsg_level(hdr) != P::TARGET_LEVEL || P::cmsg_type(hdr) != P::TARGET_TYPE {
            continue;
        }
        if P::cmsg_len(hdr) < needed {
            return None;
        }
        // SAFETY:
        // - `cmsg_len(hdr) >= cmsg_hdr_size + sizeof::<P::Cred>()` checked
        //   immediately above.
        // - The iterator already proved `cursor + cmsg_len(hdr) <=
        //   controllen`, so the payload lies fully inside the readable region.
        // - `data_ptr` is derived from the iterator's `self.base` (full-buffer
        //   provenance) — not from the `hdr` reference — so retagging into a
        //   larger credential type is provenance-clean under Stacked Borrows.
        // - The buffer outlives this call (stack-allocated in
        //   `recv_authenticated`) — satisfying `extract_pid_uid`'s contract.
        let payload_len = P::cmsg_len(hdr).saturating_sub(P::cmsg_hdr_size());
        return unsafe { P::extract_pid_uid(data_ptr, payload_len) };
    }
    None
}

// ---------------------------------------------------------------------------
// Miri-compatible tests
// ---------------------------------------------------------------------------

/// Miri-compatible cmsg pointer-walk tests.
///
/// These tests fabricate the bytes that `recvmsg(2)` would produce — no
/// actual syscall, so Miri can execute the cmsg pointer arithmetic end-to-end
/// with `-Zmiri-strict-provenance` to catch int-to-pointer casts and
/// provenance violations.
///
/// Gated on `target_os = "linux"` because the Linux `plat` module is the
/// only one currently exposed on the test host.  The unified walker is
/// generic, so this single test surface validates pointer arithmetic for
/// both platform implementations.
#[cfg(all(test, target_os = "linux"))]
mod miri_cmsg_tests {
    use super::super::plat;
    use super::*;
    use core::mem;

    /// Local shim: the existing Linux test surface called the previously
    /// standalone `cmsg_hdr_size()`. After the walker was unified the
    /// authoritative size lives on the trait; this preserves the original
    /// call sites without a sweep of every test body.
    fn cmsg_hdr_size() -> usize {
        <plat::LinuxCmsg as CmsgPlatform>::cmsg_hdr_size()
    }

    /// CMSG_SPACE for one `Ucred` on this platform.
    fn cmsg_space_ucred() -> usize {
        cmsg_align(cmsg_hdr_size() + mem::size_of::<plat::Ucred>())
    }

    /// 8-byte-aligned scratch buffer for cmsg walker tests.
    ///
    /// Plain `[u8; N]` arrays guarantee only 1-byte alignment. Miri flags
    /// `unsafe { &*hdr_ptr }` (needs 8-byte alignment for `Cmsghdr.cmsg_len:
    /// usize`) as UB when the backing allocation has alignment 1.
    /// `#[repr(align(8))]` ensures `buf.as_ptr()` is 8-byte aligned; combined
    /// with `cmsg_align`-bounded cursor advances every `base + cursor` pointer
    /// meets the alignment requirement. Pattern matches production `AncBuf` in
    /// `recv.rs`. See cerebrum 2026-05-16.
    #[repr(align(8))]
    struct AlignedBuf([u8; 512]);

    /// Write a single SCM_CREDENTIALS `cmsghdr + ucred` into `buf` starting
    /// at `offset`.  Returns the number of bytes written (== CMSG_SPACE).
    fn write_scm_credentials(buf: &mut [u8], offset: usize, pid: i32, uid: u32, gid: u32) {
        let hdr_size = cmsg_hdr_size();
        let total = cmsg_space_ucred();
        let slice = &mut buf[offset..offset + total];

        // Zero the region so padding bytes are deterministic.
        slice.fill(0);

        // Write cmsghdr fields at offset 0: cmsg_len, cmsg_level, cmsg_type.
        // On 64-bit Linux: cmsg_len is usize (8 bytes), then two i32 (4 bytes each).
        let cmsg_len: usize = hdr_size + mem::size_of::<plat::Ucred>();
        slice[..mem::size_of::<usize>()].copy_from_slice(&cmsg_len.to_ne_bytes());
        slice[mem::size_of::<usize>()..mem::size_of::<usize>() + 4]
            .copy_from_slice(&plat::SOL_SOCKET.to_ne_bytes());
        slice[mem::size_of::<usize>() + 4..mem::size_of::<usize>() + 8]
            .copy_from_slice(&plat::SCM_CREDENTIALS.to_ne_bytes());

        // Write ucred at hdr_size: pid (i32), uid (u32), gid (u32).
        let ucred_off = hdr_size;
        slice[ucred_off..ucred_off + 4].copy_from_slice(&pid.to_ne_bytes());
        slice[ucred_off + 4..ucred_off + 8].copy_from_slice(&uid.to_ne_bytes());
        slice[ucred_off + 8..ucred_off + 12].copy_from_slice(&gid.to_ne_bytes());
    }

    /// Build a `plat::Msghdr` that points into `anc_buf` with `controllen` bytes
    /// of valid ancillary data.
    fn make_mhdr(anc_buf: &[u8], controllen: usize) -> plat::Msghdr {
        plat::Msghdr {
            msg_name: core::ptr::null_mut(),
            msg_namelen: 0,
            _pad1: 0,
            msg_iov: core::ptr::null_mut(),
            msg_iovlen: 0,
            msg_control: anc_buf.as_ptr() as *mut _,
            msg_controllen: controllen,
            msg_flags: 0,
            _pad2: 0,
        }
    }

    #[test]
    fn empty_buffer_returns_none() {
        let buf = [];
        let mhdr = make_mhdr(&buf, 0);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, None);
    }

    #[test]
    fn single_scm_credentials_returns_pid_uid() {
        let mut abuf = AlignedBuf([0u8; 512]);
        write_scm_credentials(&mut abuf.0, 0, 1234, 1000, 100);
        let controllen = cmsg_space_ucred();
        let mhdr = make_mhdr(&abuf.0, controllen);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, Some((1234, 1000)));
    }

    #[test]
    fn truncated_cmsg_length_returns_none() {
        // Write a cmsg whose cmsg_len is smaller than hdr+ucred.
        let mut abuf = AlignedBuf([0u8; 512]);
        let buf = &mut abuf.0;
        let hdr_size = cmsg_hdr_size();
        // cmsg_len = hdr_size only (no room for ucred).
        let truncated_len: usize = hdr_size;
        buf[..mem::size_of::<usize>()].copy_from_slice(&truncated_len.to_ne_bytes());
        buf[mem::size_of::<usize>()..mem::size_of::<usize>() + 4]
            .copy_from_slice(&plat::SOL_SOCKET.to_ne_bytes());
        buf[mem::size_of::<usize>() + 4..mem::size_of::<usize>() + 8]
            .copy_from_slice(&plat::SCM_CREDENTIALS.to_ne_bytes());
        let controllen = cmsg_space_ucred();
        let mhdr = make_mhdr(buf, controllen);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, None, "truncated cmsg must not produce a pid");
    }

    #[test]
    fn unknown_cmsg_type_returns_none() {
        let mut abuf = AlignedBuf([0u8; 512]);
        let buf = &mut abuf.0;
        // Write a valid-length cmsg but with a different cmsg_type.
        let hdr_size = cmsg_hdr_size();
        let cmsg_len: usize = hdr_size + mem::size_of::<plat::Ucred>();
        buf[..mem::size_of::<usize>()].copy_from_slice(&cmsg_len.to_ne_bytes());
        buf[mem::size_of::<usize>()..mem::size_of::<usize>() + 4]
            .copy_from_slice(&plat::SOL_SOCKET.to_ne_bytes());
        let wrong_type: i32 = 99;
        buf[mem::size_of::<usize>() + 4..mem::size_of::<usize>() + 8]
            .copy_from_slice(&wrong_type.to_ne_bytes());
        // controllen too small for a second cmsg → walk stops after one cmsg.
        let controllen = cmsg_space_ucred();
        let mhdr = make_mhdr(buf, controllen);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, None, "unknown cmsg_type must not produce a pid");
    }

    #[test]
    fn multiple_cmsgs_finds_credentials_in_second() {
        // First cmsg: unknown type, second cmsg: SCM_CREDENTIALS.
        let space = cmsg_space_ucred();
        let mut abuf = AlignedBuf([0u8; 512]);
        let buf = &mut abuf.0;

        // First cmsg — unknown type, valid length.
        let hdr_size = cmsg_hdr_size();
        let cmsg_len: usize = hdr_size + mem::size_of::<plat::Ucred>();
        buf[..mem::size_of::<usize>()].copy_from_slice(&cmsg_len.to_ne_bytes());
        buf[mem::size_of::<usize>()..mem::size_of::<usize>() + 4]
            .copy_from_slice(&plat::SOL_SOCKET.to_ne_bytes());
        let wrong_type: i32 = 99;
        buf[mem::size_of::<usize>() + 4..mem::size_of::<usize>() + 8]
            .copy_from_slice(&wrong_type.to_ne_bytes());

        // Second cmsg — SCM_CREDENTIALS with pid=5678.
        write_scm_credentials(buf, space, 5678, 2000, 200);

        let controllen = space * 2;
        let mhdr = make_mhdr(buf, controllen);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, Some((5678, 2000)));
    }

    #[test]
    fn trailing_padding_does_not_confuse_walker() {
        // A single SCM_CREDENTIALS cmsg followed by extra zero bytes.
        let mut abuf = AlignedBuf([0u8; 512]);
        write_scm_credentials(&mut abuf.0, 0, 999, 42, 42);
        // Report controllen as the full buffer — walker must stop at the
        // cmsg whose cmsg_len does not leave room for another header.
        let controllen = 128;
        let mhdr = make_mhdr(&abuf.0, controllen);
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, Some((999, 42)));
    }

    /// Drives the unified walker through the BSD-family arm
    /// (`SCM_CREDS` + `struct cmsgcred`) on the Linux test host.
    ///
    /// The BSD `Cmsghdr` / `Cmsgcred` / `Msghdr` type definitions plus the
    /// `unsafe impl CmsgPlatform for BsdCmsg` body are compiled unconditionally
    /// on Linux (see `peer_cred/platform/mod.rs`). The FFI and `LOCAL_CREDS`
    /// constants stay gated to the actual BSD targets. This test fabricates a
    /// well-formed BSD ancillary buffer and asserts `find_credential::<BsdCmsg>`
    /// returns the expected `(pid, euid)` pair.
    ///
    /// Without this test, the BSD walker arm is only exercised on a real
    /// BSD CI host — which CI doesn't currently provide. Running it under
    /// Miri here proves the pointer arithmetic of the unified walker is
    /// provenance-clean for the BSD-shaped layout too.
    #[test]
    fn bsd_shape_buffer_returns_pid_euid() {
        use super::super::platform::bsd::{BsdCmsg, Cmsgcred, Cmsghdr, Msghdr};
        use core::mem;

        // BSD: cmsg_align uses sizeof(usize) on 64-bit, same as Linux.
        // BSD Cmsghdr is 12 bytes; cmsg_align(12) = 16.
        let bsd_hdr_size = <BsdCmsg as CmsgPlatform>::cmsg_hdr_size();
        assert_eq!(bsd_hdr_size, cmsg_align(mem::size_of::<Cmsghdr>()));
        assert_eq!(bsd_hdr_size, 16);

        let total = bsd_hdr_size + mem::size_of::<Cmsgcred>();
        let aligned_total = cmsg_align(total);
        // CRITICAL: Match recv.rs's AncBuf pattern — the buffer MUST be
        // aligned to 8 bytes. A Vec<u8> only guarantees 1-byte alignment,
        // which causes miri to detect unaligned pointer dereferences.
        // Use a stack array wrapped in #[repr(align(8))].
        #[repr(align(8))]
        struct AlignedBuf([u8; 256]);
        let mut buf_wrapper = AlignedBuf([0u8; 256]);
        let buf = &mut buf_wrapper.0[..aligned_total];

        // Write BSD cmsghdr at offset 0:
        //   cmsg_len (u32, 4 bytes), cmsg_level (i32, 4), cmsg_type (i32, 4)
        let cmsg_len: u32 = total as u32;
        let sol_socket: i32 = 0xffff; // SOL_SOCKET on BSD
        let scm_creds: i32 = 0x03; // SCM_CREDS
        buf[0..4].copy_from_slice(&cmsg_len.to_ne_bytes());
        buf[4..8].copy_from_slice(&sol_socket.to_ne_bytes());
        buf[8..12].copy_from_slice(&scm_creds.to_ne_bytes());

        // Write cmsgcred at offset bsd_hdr_size (16):
        //   cmcred_pid (i32, 4) @ 0, cmcred_uid (u32, 4) @ 4,
        //   cmcred_euid (u32, 4) @ 8, ... (rest zeroed)
        let expected_pid: i32 = 9999;
        let expected_uid: u32 = 33;
        let expected_euid: u32 = 1500;
        let cred_off = bsd_hdr_size;
        buf[cred_off..cred_off + 4].copy_from_slice(&expected_pid.to_ne_bytes());
        buf[cred_off + 4..cred_off + 8].copy_from_slice(&expected_uid.to_ne_bytes());
        buf[cred_off + 8..cred_off + 12].copy_from_slice(&expected_euid.to_ne_bytes());

        // Construct a BSD Msghdr pointing at the fabricated buffer. The
        // pure-data struct layout is identical to actual BSD on the Linux
        // test host (see compile-time offset asserts in platform/bsd.rs).
        let mhdr = Msghdr {
            msg_name: core::ptr::null_mut(),
            msg_namelen: 0,
            _pad1: 0,
            msg_iov: core::ptr::null_mut(),
            msg_iovlen: 0,
            _pad2: 0,
            msg_control: buf.as_mut_ptr() as *mut _,
            msg_controllen: aligned_total as u32,
            msg_flags: 0,
        };

        let result = find_credential::<BsdCmsg>(&mhdr);
        assert_eq!(result, Some((expected_pid as u32, expected_euid)));
    }

    /// Drives the unified walker through the illumos/Solaris arm
    /// (`SCM_UCRED` + opaque `ucred_t`) on the Linux test host.
    ///
    /// The illumos `Cmsghdr` / `Msghdr` type definitions and the
    /// `unsafe impl CmsgPlatform for IllumosCmsg` body are compiled on Linux
    /// too (see `peer_cred/platform/mod.rs`). The `extern "C"` `ucred_getpid`
    /// / `ucred_geteuid` accessors are replaced by inline Rust shims that read
    /// PID at offset 0 (i32) and UID at offset 4 (u32) of the test buffer.
    ///
    /// Without this test the illumos walker arm is only exercised on a real
    /// illumos CI host.  Running it under Miri here proves pointer arithmetic
    /// is provenance-clean for the illumos-shaped layout too.
    #[test]
    fn illumos_shape_buffer_returns_pid_euid() {
        use super::super::platform::illumos::{Cmsghdr, IllumosCmsg, Msghdr};
        use core::mem;

        // illumos Cmsghdr is 12 bytes; cmsg_align(12) = 16 on LP64.
        let illumos_hdr_size = <IllumosCmsg as CmsgPlatform>::cmsg_hdr_size();
        assert_eq!(illumos_hdr_size, cmsg_align(mem::size_of::<Cmsghdr>()));
        assert_eq!(illumos_hdr_size, 16);

        // Payload: 4 bytes pid (i32) + 4 bytes uid (u32) = 8 bytes.
        // The shim reads pid at offset 0, uid at offset 4 of the payload.
        let payload_len = 8usize;
        let total = illumos_hdr_size + payload_len;
        let aligned_total = cmsg_align(total);
        // CRITICAL: Match recv.rs's AncBuf pattern — the buffer MUST be
        // aligned to 8 bytes. A Vec<u8> only guarantees 1-byte alignment,
        // which causes miri to detect unaligned pointer dereferences.
        // Use a stack array wrapped in #[repr(align(8))].
        #[repr(align(8))]
        struct AlignedBuf([u8; 256]);
        let mut buf_wrapper = AlignedBuf([0u8; 256]);
        let buf = &mut buf_wrapper.0[..aligned_total];

        // Write illumos cmsghdr: cmsg_len (u32), cmsg_level (i32), cmsg_type (i32)
        let cmsg_len: u32 = total as u32;
        let sol_socket: i32 = 0xffff; // SOL_SOCKET on illumos
        let scm_ucred: i32 = 0x1012; // SCM_UCRED
        buf[0..4].copy_from_slice(&cmsg_len.to_ne_bytes());
        buf[4..8].copy_from_slice(&sol_socket.to_ne_bytes());
        buf[8..12].copy_from_slice(&scm_ucred.to_ne_bytes());

        // Write test payload at illumos_hdr_size: pid at +0, uid at +4.
        let expected_pid: i32 = 4321;
        let expected_uid: u32 = 500;
        let pay_off = illumos_hdr_size;
        buf[pay_off..pay_off + 4].copy_from_slice(&expected_pid.to_ne_bytes());
        buf[pay_off + 4..pay_off + 8].copy_from_slice(&expected_uid.to_ne_bytes());

        let mhdr = Msghdr {
            msg_name: core::ptr::null_mut(),
            msg_namelen: 0,
            _pad1: 0,
            msg_iov: core::ptr::null_mut(),
            msg_iovlen: 0,
            _pad2: 0,
            msg_control: buf.as_mut_ptr() as *mut _,
            msg_controllen: aligned_total as u32,
            msg_flags: 0,
        };

        let result = find_credential::<IllumosCmsg>(&mhdr);
        assert_eq!(result, Some((expected_pid as u32, expected_uid)));
    }

    /// `ucred_getpid` shim returns -1 when the buffer encodes a negative pid
    /// → `extract_pid_uid` returns `None`.
    #[test]
    fn illumos_opaque_extraction_returns_none_on_invalid() {
        use super::super::platform::illumos::{IllumosCmsg, Msghdr};

        let illumos_hdr_size = <IllumosCmsg as CmsgPlatform>::cmsg_hdr_size();
        let payload_len = 8usize;
        let total = illumos_hdr_size + payload_len;
        let aligned_total = cmsg_align(total);
        // CRITICAL: Match recv.rs's AncBuf pattern — the buffer MUST be
        // aligned to 8 bytes.
        #[repr(align(8))]
        struct AlignedBuf([u8; 256]);
        let mut buf_wrapper = AlignedBuf([0u8; 256]);
        let buf = &mut buf_wrapper.0[..aligned_total];

        let cmsg_len: u32 = total as u32;
        let sol_socket: i32 = 0xffff;
        let scm_ucred: i32 = 0x1012;
        buf[0..4].copy_from_slice(&cmsg_len.to_ne_bytes());
        buf[4..8].copy_from_slice(&sol_socket.to_ne_bytes());
        buf[8..12].copy_from_slice(&scm_ucred.to_ne_bytes());

        // Encode pid = -1 → shim returns -1 → extract_pid_uid returns None.
        let neg_pid: i32 = -1;
        let uid: u32 = 1000;
        let pay_off = illumos_hdr_size;
        buf[pay_off..pay_off + 4].copy_from_slice(&neg_pid.to_ne_bytes());
        buf[pay_off + 4..pay_off + 8].copy_from_slice(&uid.to_ne_bytes());

        let mhdr = Msghdr {
            msg_name: core::ptr::null_mut(),
            msg_namelen: 0,
            _pad1: 0,
            msg_iov: core::ptr::null_mut(),
            msg_iovlen: 0,
            _pad2: 0,
            msg_control: buf.as_mut_ptr() as *mut _,
            msg_controllen: aligned_total as u32,
            msg_flags: 0,
        };

        let result = find_credential::<IllumosCmsg>(&mhdr);
        assert_eq!(result, None, "negative pid must produce None");
    }

    /// `cmsg_len` smaller than the minimum (hdr_size + 0) must be rejected.
    #[test]
    fn illumos_walker_rejects_truncated_cmsg() {
        use super::super::platform::illumos::{IllumosCmsg, Msghdr};

        let illumos_hdr_size = <IllumosCmsg as CmsgPlatform>::cmsg_hdr_size();

        // Claim cmsg_len = hdr_size - 1 (strictly less than needed = hdr_size).
        let truncated_len: u32 = (illumos_hdr_size - 1) as u32;
        // CRITICAL: Match recv.rs's AncBuf pattern — the buffer MUST be
        // aligned to 8 bytes.
        #[repr(align(8))]
        struct AlignedBuf([u8; 256]);
        let mut buf_wrapper = AlignedBuf([0u8; 256]);
        let buf = &mut buf_wrapper.0[..illumos_hdr_size + 8];

        buf[0..4].copy_from_slice(&truncated_len.to_ne_bytes());
        let sol_socket: i32 = 0xffff;
        let scm_ucred: i32 = 0x1012;
        buf[4..8].copy_from_slice(&sol_socket.to_ne_bytes());
        buf[8..12].copy_from_slice(&scm_ucred.to_ne_bytes());

        let mhdr = Msghdr {
            msg_name: core::ptr::null_mut(),
            msg_namelen: 0,
            _pad1: 0,
            msg_iov: core::ptr::null_mut(),
            msg_iovlen: 0,
            _pad2: 0,
            msg_control: buf.as_mut_ptr() as *mut _,
            msg_controllen: buf.len() as u32,
            msg_flags: 0,
        };

        let result = find_credential::<IllumosCmsg>(&mhdr);
        assert_eq!(
            result, None,
            "truncated illumos cmsg must not produce a pid"
        );
    }

    /// Defense-in-depth: an attacker-supplied cmsg_len of 0 must not loop
    /// forever. The walker advances by at least `cmsg_hdr_size` per step.
    #[test]
    fn zero_cmsg_len_does_not_infinite_loop() {
        let mut abuf = AlignedBuf([0u8; 512]);
        let buf = &mut abuf.0;
        // Write a cmsg with cmsg_len == 0 but otherwise valid header bytes.
        let zero_len: usize = 0;
        buf[..mem::size_of::<usize>()].copy_from_slice(&zero_len.to_ne_bytes());
        buf[mem::size_of::<usize>()..mem::size_of::<usize>() + 4]
            .copy_from_slice(&plat::SOL_SOCKET.to_ne_bytes());
        buf[mem::size_of::<usize>() + 4..mem::size_of::<usize>() + 8]
            .copy_from_slice(&plat::SCM_CREDENTIALS.to_ne_bytes());
        let mhdr = make_mhdr(buf, buf.len());
        // Must return None — cmsg_len < needed; must terminate (test would
        // hang otherwise).
        let result = plat::peer_pid_after_recv(0, &mhdr);
        assert_eq!(result, None);
    }
}