mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-17 02:56:51 +00:00
* fixed a nasty bug in epoll_loop() and poll_loop() by which an EPOLL_HUP event
could trigger both a read and a write calls, thus sometimes inducing headers being directly sent from srv to cli without modification, and leading further modification to crash the process by memory corruption, because rep.data+rep.l<rep.h so the memmove() length argument is negative. Only observed with epoll() and never poll(), though this one should have been affected too. Now, only call functions which have been allowed to.
This commit is contained in:
parent
11a4606c8b
commit
e78ae269fe
33
haproxy.c
33
haproxy.c
@ -2967,6 +2967,10 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, char *str, int len)
|
||||
if (delta + b->r >= b->data + BUFSIZE)
|
||||
return 0; /* no space left */
|
||||
|
||||
if (b->data + b->l < end)
|
||||
/* The data has been stolen, we could have crashed. Maybe we should abort() ? */
|
||||
return 0;
|
||||
|
||||
/* first, protect the end of the buffer */
|
||||
memmove(end + delta, end, b->data + b->l - end);
|
||||
|
||||
@ -4194,7 +4198,10 @@ int process_srv(struct session *t) {
|
||||
if (t->proxy->options & PR_O_COOK_NOC)
|
||||
//len += sprintf(newhdr + len, "Cache-control: no-cache=\"set-cookie\"\r\n");
|
||||
len += sprintf(trash + len, "Cache-control: private\r\n");
|
||||
|
||||
|
||||
if (rep->data + rep->l < rep->h)
|
||||
/* The data has been stolen, we will crash cleanly instead of corrupting memory */
|
||||
*(int *)0 = 0;
|
||||
buffer_replace2(rep, rep->h, rep->h, trash, len);
|
||||
}
|
||||
|
||||
@ -5354,14 +5361,18 @@ int epoll_loop(int action) {
|
||||
if (fdtab[fd].state == FD_STCLOSE)
|
||||
continue;
|
||||
|
||||
if (epoll_events[count].events & ( EPOLLIN | EPOLLERR | EPOLLHUP ))
|
||||
fdtab[fd].read(fd);
|
||||
if (epoll_events[count].events & ( EPOLLIN | EPOLLERR | EPOLLHUP )) {
|
||||
if (FD_ISSET(fd, StaticReadEvent))
|
||||
fdtab[fd].read(fd);
|
||||
}
|
||||
|
||||
if (fdtab[fd].state == FD_STCLOSE)
|
||||
continue;
|
||||
|
||||
if (epoll_events[count].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP ))
|
||||
fdtab[fd].write(fd);
|
||||
if (epoll_events[count].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP )) {
|
||||
if (FD_ISSET(fd, StaticWriteEvent))
|
||||
fdtab[fd].write(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -5475,14 +5486,18 @@ int poll_loop(int action) {
|
||||
if (fdtab[fd].state == FD_STCLOSE)
|
||||
continue;
|
||||
|
||||
if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP ))
|
||||
fdtab[fd].read(fd);
|
||||
if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP )) {
|
||||
if (FD_ISSET(fd, StaticReadEvent))
|
||||
fdtab[fd].read(fd);
|
||||
}
|
||||
|
||||
if (fdtab[fd].state == FD_STCLOSE)
|
||||
continue;
|
||||
|
||||
if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP ))
|
||||
fdtab[fd].write(fd);
|
||||
if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP )) {
|
||||
if (FD_ISSET(fd, StaticWriteEvent))
|
||||
fdtab[fd].write(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user