Skip to content

Fixes UB of recvmmsg and simplifies signatures of recvmmsg and sendmmsg #2120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 1, 2023

Conversation

Jan561
Copy link
Contributor

@Jan561 Jan561 commented Sep 2, 2023

The signature of recvmmsg gets changed to:

pub fn recvmmsg<'a, XS, S, I>(
    fd: RawFd,
    data: &'a mut MultiHeaders<S>,
    slices: XS,
    flags: MsgFlags,
    mut timeout: Option<crate::sys::time::TimeSpec>,
) -> crate::Result<MultiResults<'a, S>>
where
    XS: IntoIterator<Item = I>,
    I: AsMut<[IoSliceMut<'a>]>,

The signature of sendmmsg gets changed to:

pub fn sendmmsg<'a, XS, AS, C, I, S>(
    fd: RawFd,
    data: &'a mut MultiHeaders<S>,
    slices: XS,
    addrs: AS,
    cmsgs: C,
    flags: MsgFlags
) -> crate::Result<MultiResults<'a, S>>
    where
        XS: IntoIterator<Item = I>,
        AS: AsRef<[Option<S>]>,
        I: AsRef<[IoSlice<'a>]>,
        C: AsRef<[ControlMessage<'a>]>,
        S: SockaddrLike,

Fixes #2119

@Jan561 Jan561 force-pushed the master branch 5 times, most recently from ad1a41b to 78cf0a2 Compare September 3, 2023 11:03
@Jan561
Copy link
Contributor Author

Jan561 commented Sep 3, 2023

I've completely disabled the personality::set doctest on my branch as it appears to be completely broken now on multiple platforms at Cirrus

@Jan561 Jan561 force-pushed the master branch 3 times, most recently from d4836e9 to 12b417a Compare September 30, 2023 12:12
@Jan561
Copy link
Contributor Author

Jan561 commented Sep 30, 2023

Thanks for your review, I've also noticed your PR #2140 and applied it to the remaining pointer conversions in both functions (except this one, which is fine imo).

Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

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

Sadly, there's another merge conflict in CHANGELOG. Could you fix that, please?

@Jan561
Copy link
Contributor Author

Jan561 commented Oct 1, 2023

Done. For the sendmmsg-change, I've written a small example of what is possible now, which wasn't possible before.

https://gist.github.com/Jan561/1e44db811698d06bb247c30bbe448fc9

Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

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

Your gist there suggests that a different API would be more convenient. This is something that I've been thinking about too. It would look something like this:

struct MsgVec<'a> {
    msgvec: Vec<libc::msghdr>,
}
impl<'a> MsgVec<'a> {
   fn with_capacity(n: usize) -> Self {...}
   fn add<S: SockaddrLike + 'a>(&mut self, to: S, I: [IoSlice<'a>], &mut cmsg: ControlMessage<'a>)
   fn reset(&mut self);
}

fn sendmmsg<F>(fd: F, msgvec: MsgVec<'_>, flags: MsgFlags)
    where F: AsFd
    {}

And you could use it something like this:

let mut msg_vec = MsgVec::with_capacity(2);
msg_vec.add(some_host, &[iovec0, iovec1][..], &[ControlMessage::ScmRights(...)][..]);
sendmmsg(&s, msg_vec);

The general idea being that the add API keeps related host, data, and control messages together rather than forcing the user to split them into 3 separate arrays. Plus, the MsgVec::reset method allows reusing storage for a MsgVec, eliminating the need to allocate on each call of sendmmsg, which was the primary problem of the earlier implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

recvmmsg may cause UB
2 participants