Revert "Revert "oran-shell-release: release image for F""
[pti/rtp.git] / meta-starlingx / meta-stx-distro / recipes-security / gssproxy / files / Fix-handling-of-non-EPOLLIN-EPOLLOUT-events.patch
1 From a2a5789d6410e12469ea0f81c9a31ce70bac9ede Mon Sep 17 00:00:00 2001
2 From: Alexander Scheel <alexander.m.scheel@gmail.com>
3 Date: Thu, 14 Sep 2017 11:16:42 -0500
4 Subject: [PATCH] Fix handling of non-EPOLLIN/EPOLLOUT events
5
6 Signed-off-by: Alexander Scheel <alexander.m.scheel@gmail.com>
7 Reviewed-by: Robbie Harwood <rharwood@redhat.com>
8 Merges: #213
9 (cherry picked from commit b8f5b2f75612a11753cf742ee0477b98df8e6b02)
10 ---
11  proxy/src/client/gpm_common.c | 49 +++++++++++++++++++++++++----------
12  1 file changed, 35 insertions(+), 14 deletions(-)
13
14 diff --git a/proxy/src/client/gpm_common.c b/proxy/src/client/gpm_common.c
15 index 7d1158e..b14e846 100644
16 --- a/proxy/src/client/gpm_common.c
17 +++ b/proxy/src/client/gpm_common.c
18 @@ -283,26 +283,47 @@ static int gpm_epoll_wait(struct gpm_ctx *gpmctx, uint32_t event_flags) {
19          gpm_epoll_close(gpmctx);
20      } else if (epoll_ret == 1 && events[0].data.fd == gpmctx->timerfd) {
21          /* Got an event which is only our timer */
22 -        ret = read(gpmctx->timerfd, &timer_read, sizeof(uint64_t));
23 -        if (ret == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
24 -            /* In the case when reading from the timer failed, don't hide the
25 -             * timer error behind ETIMEDOUT such that it isn't retried */
26 -            ret = errno;
27 +        if ((events[0].events & EPOLLIN) == 0) {
28 +            /* We got an event which was not EPOLLIN; assume this is an error,
29 +             * and exit with EBADF: epoll_wait said timerfd had an event,
30 +             * but that event is not an EPOLIN event. */
31 +            ret = EBADF;
32          } else {
33 -            /* If ret == 0, then we definitely timed out. Else, if ret == -1
34 -             * and errno == EAGAIN or errno == EWOULDBLOCK, we're in a weird
35 -             * edge case where epoll thinks the timer can be read, but it
36 -             * is blocking more; treat it like a TIMEOUT and retry, as
37 -             * nothing around us would handle EAGAIN from timer and retry
38 -             * it. */
39 -            ret = ETIMEDOUT;
40 +            ret = read(gpmctx->timerfd, &timer_read, sizeof(uint64_t));
41 +            if (ret == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
42 +                /* In the case when reading from the timer failed, don't hide the
43 +                 * timer error behind ETIMEDOUT such that it isn't retried */
44 +                ret = errno;
45 +            } else {
46 +                /* If ret == 0, then we definitely timed out. Else, if ret == -1
47 +                 * and errno == EAGAIN or errno == EWOULDBLOCK, we're in a weird
48 +                 * edge case where epoll thinks the timer can be read, but it
49 +                 * is blocking more; treat it like a TIMEOUT and retry, as
50 +                 * nothing around us would handle EAGAIN from timer and retry
51 +                 * it. */
52 +                ret = ETIMEDOUT;
53 +            }
54          }
55          gpm_epoll_close(gpmctx);
56      } else {
57          /* If ret == 2, then we ignore the timerfd; that way if the next
58           * operation cannot be performed immediately, we timeout and retry.
59 -         * If ret == 1 and data.fd == gpmctx->fd, return 0. */
60 -        ret = 0;
61 +         * Always check the returned event of the socket fd. */
62 +        int fd_index = 0;
63 +        if (epoll_ret == 2 && events[fd_index].data.fd != gpmctx->fd) {
64 +            fd_index = 1;
65 +        }
66 +
67 +        if ((events[fd_index].events & event_flags) == 0) {
68 +            /* We cannot call EPOLLIN/EPOLLOUT at this time; assume that this
69 +             * is a fatal error; return with EBADFD to distinguish from
70 +             * EBADF in timer_fd case. */
71 +            ret = EBADFD;
72 +            gpm_epoll_close(gpmctx);
73 +        } else {
74 +            /* We definintely got a EPOLLIN/EPOLLOUT event; return success. */
75 +            ret = 0;
76 +        }
77      }
78  
79      epoll_ret = epoll_ctl(gpmctx->epollfd, EPOLL_CTL_DEL, gpmctx->fd, NULL);