Skip to content

Conversation

@xingxue-ibm
Copy link
Contributor

Description

AIX does not apply any alignment or padding to ancillary data, and CMSG_ALIGN() is a no-op. Therefore, we only test addresses that are multiples of the size of cmsghdr on AIX. The original condition for AIX was removed in f391df3, which led to the test failure.

Sources

Checklist

  • Relevant tests in libc-test/semver have been updated
  • No placeholder or unstable values like *LAST or *MAX are
    included (see #3131)
  • Tested locally (cd libc-test && cargo test --target mytarget);
    especially relevant for platforms that may not be checked in CI

@xingxue-ibm xingxue-ibm force-pushed the aix-test-multiple-cmsghdr-size-only branch from c7b3a6a to 9fd9f59 Compare January 6, 2026 19:37
@xingxue-ibm xingxue-ibm marked this pull request as ready for review January 6, 2026 19:50
Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry about that, I incorrectly assumed the AIX-specific bit was a result of the boundary check issues fixed in that commit. Thanks for the fix!

Cc @gibbz00

@tgross35 tgross35 enabled auto-merge January 6, 2026 22:31
@tgross35 tgross35 added the stable-nominated This PR should be considered for cherry-pick to libc's stable release branch label Jan 6, 2026
@tgross35 tgross35 added this pull request to the merge queue Jan 6, 2026
Merged via the queue into rust-lang:main with commit 85a3691 Jan 6, 2026
93 of 147 checks passed
@gibbz00
Copy link
Contributor

gibbz00 commented Jan 6, 2026

@xingxue-ibm

I'm sorry, but I don't understand how this makes sense. You say that AIX does not apply any padding, yet the payload is required to be a multiple of size_of::<cmsghdr>? Sounds to me like AIX's CMSG_ALIGN then be:

fn CMSG_ALIGN(len: usize) -> usize { (len + size_of::<cmsghdr>() - 1) & !(size_of::<cmsghdr>() - 1) }

How do you otherwise deal with payloads that aren't multiples of exactly cmsghdr bytes? Say when sending only one file descriptor over a unix socket?

@gibbz00
Copy link
Contributor

gibbz00 commented Jan 6, 2026

... Or in other words, to me it sounds like the AIX C implementation does apply padding, but the Rust implementation doesn't, hence the test failure. If so, then the solution shouldn't be to ignore the test values where the implementations differ, but rather fix the Rust implementation. This may be easier with setting the __ALIGN_BOUNDARY from #4908, but I doubt it will land in before 1.0.

What kind of test failures were you getting?

@xingxue-ibm
Copy link
Contributor Author

@xingxue-ibm

I'm sorry, but I don't understand how this makes sense. You say that AIX does not apply any padding, yet the payload is required to be a multiple of size_of::<cmsghdr>? Sounds to me like AIX's CMSG_ALIGN then be:

fn CMSG_ALIGN(len: usize) -> usize { (len + size_of::<cmsghdr>() - 1) & !(size_of::<cmsghdr>() - 1) }

How do you otherwise deal with payloads that aren't multiples of exactly cmsghdr bytes? Say when sending only one file descriptor over a unix socket?

The AIX <sys/socket.h> defines _CMSG_ALIGN as follows.

/* AIX does not have any alignment/padding for ancillary data */
#define _CMSG_ALIGN(p)      (p)

So, the Rust libc does not use _CMSG_ALIGN, for example:

    pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr {
        if cmsg.is_null() {
            CMSG_FIRSTHDR(mhdr)
        } else {
            if (cmsg as usize + (*cmsg).cmsg_len as usize + size_of::<cmsghdr>())
                > ((*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize)
            {
                core::ptr::null_mut::<cmsghdr>()
            } else {
                // AIX does not have any alignment/padding for ancillary data, so we don't need _CMSG_ALIGN here.
                (cmsg as usize + (*cmsg).cmsg_len as usize) as *mut cmsghdr
            }
        }
    }

@xingxue-ibm
Copy link
Contributor Author

... Or in other words, to me it sounds like the AIX C implementation does apply padding, but the Rust implementation doesn't, hence the test failure. If so, then the solution shouldn't be to ignore the test values where the implementations differ, but rather fix the Rust implementation. This may be easier with setting the __ALIGN_BOUNDARY from #4908, but I doubt it will land in before 1.0.

What kind of test failures were you getting?

The test failed with the following error:

thread 't::test_cmsg_nxthdr' panicked at libc-test/tests/cmsg.rs:86:25:
misaligned pointer dereference: address must be a multiple of 0x4 but is 0x1108c63e5

Where line 86 is:

 86                         (*current_cmsghdr_ptr).cmsg_len =
 87                             libc::CMSG_LEN(cmsg_payload_len as _) as _;

@gibbz00
Copy link
Contributor

gibbz00 commented Jan 7, 2026

Thanks for the quick response.

If you don't mind me asking, how does AIX's CMSG_SPACE C definition look like?

@xingxue-ibm
Copy link
Contributor Author

If you don't mind me asking, how does AIX's CMSG_SPACE C definition look like?

...
/* AIX does not have any alignment/padding for ancillary data */
#define _CMSG_ALIGN(p)      (p)
...
#define CMSG_ALIGN          _CMSG_ALIGN
#define CMSG_SPACE(len)     (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))

@gibbz00
Copy link
Contributor

gibbz00 commented Jan 7, 2026

Oh wow, interesting. So it's not that AIX supports unaligned access, but more so that it doesn't try to account for it at all.

Misaligned pointer dereference: address must be a multiple of 0x4 but is 0x1108c63e5

If I'm reading that correctly, isn't the minimum alignment 4 bytes? Not cmsghdr's 16?

Did the tests not work with cmsg_payload_len % std::mem::size_of::<u32>() != 0?

That would explain a lot about how it doesn't affect AIX in practice. Can't think of any cmsg payload that isn't divisible to 4.

@xingxue-ibm
Copy link
Contributor Author

Yes, cmsg_payload_len % std::mem::size_of::<u32>() != 0 works as well.

tgross35 pushed a commit to tgross35/rust-libc that referenced this pull request Jan 8, 2026
@tgross35 tgross35 mentioned this pull request Jan 8, 2026
github-merge-queue bot pushed a commit that referenced this pull request Jan 8, 2026
@tgross35 tgross35 added stable-applied This PR has been cherry-picked to libc's stable release branch and removed stable-nominated This PR should be considered for cherry-pick to libc's stable release branch labels Jan 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stable-applied This PR has been cherry-picked to libc's stable release branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants