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)