Skip to content

GUACAMOLE-2238: Multiple guacamole-server code paths do not correctly…#643

Open
bbennett-ks wants to merge 1 commit intoapache:staging/1.6.1from
bbennett-ks:GUACAMOLE-2238-retry-on-eintr-refactor
Open

GUACAMOLE-2238: Multiple guacamole-server code paths do not correctly…#643
bbennett-ks wants to merge 1 commit intoapache:staging/1.6.1from
bbennett-ks:GUACAMOLE-2238-retry-on-eintr-refactor

Conversation

@bbennett-ks
Copy link
Contributor

Summary

This PR hardens blocking I/O and wait paths against signal interruption (EINTR).

When a signal is delivered (e.g. when a child process exits), some blocking syscalls can return early with -1 with errno = EINTR . This is not a hard failure: the syscall should be retried.

This PR adds EINTR retry loops around blocking calls in various guacamole-server. Equivalent handling for the Windows equivalent was also added.

Without retry, signal (async) delivery can cause a variety of errors: network connections errors, read/write failures, premature timeouts...

select Handling

int select(int nfds, fd_set *_Nullable restrict readfds, fd_set *_Nullable restrict writefds, fd_set *_Nullable restrict exceptfds, struct timeval *_Nullable restrict timeout);

Special care has been taken with the select system call, as it has parameters which are modified by the system: how these parameters are handled on retry must be considered. Based on the Linux man page:

On error, -1 is returned, and is set to indicate the error; the file descriptor sets are unmodified, and timeout becomes undefined.

select retry is based on this.

@necouchman
Copy link
Contributor

Looks pretty good to me, @bbennett-ks. Just going to see if @mike-jumper has any comments or concerns before merging this. I'm wondering if this will help resolve some of the other bugs we have lingering, like 1998, which deals with hung processes and the like.

@necouchman necouchman requested a review from mike-jumper March 6, 2026 23:33
@bbennett-ks bbennett-ks force-pushed the GUACAMOLE-2238-retry-on-eintr-refactor branch from 2f630cc to db0f828 Compare March 7, 2026 00:44
@bbennett-ks
Copy link
Contributor Author

  • I didn't check for send/recvmsg(): updated.
  • Also, mention of 1998 made me think of another select() issue: fd_set overflow: updated.

@bbennett-ks
Copy link
Contributor Author

Looks pretty good to me, @bbennett-ks. Just going to see if @mike-jumper has any comments or concerns before merging this. I'm wondering if this will help resolve some of the other bugs we have lingering, like 1998, which deals with hung processes and the like.

An instance of this issue (GUACAMOLE-2239) was identified as the core cause of one intermittent issue.

Copy link
Contributor

@mike-jumper mike-jumper left a comment

Choose a reason for hiding this comment

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

It'd be good to be a bit more DRY. Otherwise, LGTM.

src/common/io.c Outdated
Comment on lines +34 to +36
do {
bytes_written = write(fd, bytes, length);
} while (bytes_written < 0 && errno == EINTR);
Copy link
Contributor

@mike-jumper mike-jumper Mar 7, 2026

Choose a reason for hiding this comment

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

There's a lot of this pattern repeated. If possible, I think we should pull anything like:

do {
    retval = do_thing(params);
} while (retval < 0 && errno == EINTR);

into libguac functions/macros that can be reused instead of duplicated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a lot of this pattern repeated. If possible, I think we should pull anything like:

do {
    retval = do_thing(params);
} while (retval < 0 && errno == EINTR);

into libguac functions/macros that can be reused instead of duplicated.

Does this approach look good?

@bbennett-ks bbennett-ks force-pushed the GUACAMOLE-2238-retry-on-eintr-refactor branch from db0f828 to 3076f6d Compare March 7, 2026 16:41
@bbennett-ks bbennett-ks marked this pull request as draft March 9, 2026 14:39
@bbennett-ks
Copy link
Contributor Author

After looking at kernel & glib source, I have a few more changes I'd like to make. I've changed the PR back to a draft.

@bbennett-ks bbennett-ks force-pushed the GUACAMOLE-2238-retry-on-eintr-refactor branch from 3076f6d to 2f7ea03 Compare March 9, 2026 15:47
@bbennett-ks bbennett-ks marked this pull request as ready for review March 9, 2026 15:49
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