From: Willy TARREAU Date: Sun, 8 Jan 2006 00:24:12 +0000 (+0100) Subject: * fixed a nasty bug in epoll_loop() and poll_loop() by which an EPOLL_HUP event X-Git-Tag: v1.2.8~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e78ae269fe90fcadd921a7eec1b2b181ea4f6181;p=thirdparty%2Fhaproxy.git * 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.lr >= 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;