Skip to content
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

libc: retry open when interrupted #252

Merged
merged 1 commit into from
Mar 25, 2022
Merged

Conversation

stoeckmann
Copy link
Contributor

The open call can be interrupted. Since sys_fill_exact covers this for
read operation already, it should be done here as well.

Signed-off-by: Tobias Stoeckmann [email protected]

Shoutout to c3h2-ctf.

Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

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

Nice catch here!!

src/util_libc.rs Outdated
Comment on lines 110 to 114
loop {
let fd = open(path.as_ptr() as *const _, libc::O_RDONLY | libc::O_CLOEXEC);
if fd < 0 {
let err = last_os_error();
// We should try again if the call was interrupted.
if err.raw_os_error() != Some(libc::EINTR) {
return Err(err);
}
} else {
return Ok(fd);
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if it's more idiomatic to do:

let mut fd;
while { fd = open(...); fd < 0 } {
    let err = last_os_error();
    // We should try again if open() was interrupted.
    if err.raw_os_error() != Some(libc::EINTR) {
        return Err(err);
    }
}
Ok(fd)

Copy link
Member

Choose a reason for hiding this comment

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

Alternatively:

loop {
    let fd = open(path.as_ptr() as *const _, libc::O_RDONLY | libc::O_CLOEXEC);
    if fd >= 0 {
        return Ok(fd);
    }
    let err = las_os_error();
    // We should try again if open() was interrupted.
    if err.raw_os_error() != Some(libc::EINTR) {
        return Err(err);
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have taken the second version, which received a thumbs up. :)

The open call can be interrupted. Since sys_fill_exact covers this for
read operation already, it should be done here as well.

Signed-off-by: Tobias Stoeckmann <[email protected]>
@josephlr
Copy link
Member

I'll give @newpavlov a little time to take a look, and then I'll merge this.

Copy link
Member

@newpavlov newpavlov left a comment

Choose a reason for hiding this comment

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

I wonder if it could be worth to limit number of retries to be extra safe by replacing loop { .. } with something like this:

for _ in 0..256 {
    // ..
}
Err(Error::TOO_MANY_ITERATIONS) // find a better name

@josephlr
Copy link
Member

I wonder if it could be worth to limit number of retries to be extra safe by replacing loop { .. } with something like this:

for _ in 0..256 {
    // ..
}
Err(Error::TOO_MANY_ITERATIONS) // find a better name

It looks like Rust's open implementation on Linux calls cvt_r and cvt_r just retries indefinitely. So we should probably mirror that behavior here.

@newpavlov newpavlov merged commit fcae1d2 into rust-random:master Mar 25, 2022
henrysun007 pushed a commit to mesatee/getrandom that referenced this pull request Nov 24, 2022
The open call can be interrupted. Since sys_fill_exact covers this for
read operation already, it should be done here as well.

Signed-off-by: Tobias Stoeckmann <[email protected]>
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.

3 participants