You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@guacamole.apache.org by "Mike Jumper (Jira)" <ji...@apache.org> on 2026/03/27 00:11:00 UTC
[jira] [Updated] (GUACAMOLE-2238) Multiple guacamole-server code paths do not correctly retry on EINTR
[ https://issues.apache.org/jira/browse/GUACAMOLE-2238?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mike Jumper updated GUACAMOLE-2238:
-----------------------------------
Fix Version/s: 1.6.1 [staging]
> Multiple guacamole-server code paths do not correctly retry on EINTR
> --------------------------------------------------------------------
>
> Key: GUACAMOLE-2238
> URL: https://issues.apache.org/jira/browse/GUACAMOLE-2238
> Project: Guacamole
> Issue Type: Bug
> Components: guacd
> Affects Versions: 1.6.0
> Reporter: Bradley Bennett
> Priority: Minor
> Fix For: 1.6.1 [staging]
>
>
> Several locations in the *guacamole-server* codebase call blocking system calls (e.g., poll(), select(), read(), etc.) and treat any -1 return value as a fatal error without checking for {*}errno == EINTR{*}.
> Because *EINTR* is triggered asynchronously by signals, this can lead to intermittent and hard-to-debug failures. In particular, *SIGCHLD* is delivered whenever a child process exits or changes state (e.g., when forked subprocesses terminate), which can interrupt blocking syscalls, causing unexpected failures if *EINTR* is not retried.
> One example that has recently been identified asthe core cause of an issue{*}: src/libguac/wait-fd.c{*}:
> {code:java}
> int guac_wait_for_fd(int fd, int usec_timeout) {
> ...
> return select(fd + 1, &fds, NULL, NULL, &timeout);{code}
> The fix is to retry if the select() fails with EINTR:
> {code:java}
> int guac_wait_for_fd(int fd, int usec_timeout) {
> ...
> do {
> ...
> /* Retry if interrupted by a signal (EINTR). */
> retval = select(fd + 1, &fds, NULL, NULL, &timeout);
> } while (retval < 0 && errno == EINTR); return retval;
> {code}
> The fix (if properly implemented) is {*}very low risk{*}, as it only retries the syscall when it was interrupted by a signal before completing. In this case the operation has not actually failed and no state has changed; retrying simply resumes the original wait as intended.
> There are numerous instances where EINTR is not handled properly for the read(), write(), poll(), select(), waitpid(), and nanosleep() system calls,
--
This message was sent by Atlassian Jira
(v8.20.10#820010)