summaryrefslogtreecommitdiffstats
path: root/src/drivers/linux
diff options
context:
space:
mode:
authorMichael Brown2017-09-04 19:00:34 +0200
committerMichael Brown2017-09-04 19:00:34 +0200
commit306465bef3fbbe14e6270fecf3e2d0c427f4bbc7 (patch)
tree97e9e07ca885fe0d4bf7be206864792752fccbef /src/drivers/linux
parent[malloc] Avoid false positive warnings from valgrind (diff)
downloadipxe-306465bef3fbbe14e6270fecf3e2d0c427f4bbc7.tar.gz
ipxe-306465bef3fbbe14e6270fecf3e2d0c427f4bbc7.tar.xz
ipxe-306465bef3fbbe14e6270fecf3e2d0c427f4bbc7.zip
[linux] Impose receive quota on tap driver
The tap driver can retrieve a potentially unlimited number of packets in a single poll. This can lead to heap exhaustion under heavy load. Fix by imposing an artificial receive quota (as already used in other drivers without natural receive limits). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/linux')
-rw-r--r--src/drivers/linux/tap.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/drivers/linux/tap.c b/src/drivers/linux/tap.c
index 6fe76fd4..db3b7955 100644
--- a/src/drivers/linux/tap.c
+++ b/src/drivers/linux/tap.c
@@ -40,6 +40,7 @@
#include <linux/if_tun.h>
#define RX_BUF_SIZE 1536
+#define RX_QUOTA 4
/** @file
*
@@ -127,6 +128,7 @@ static void tap_poll(struct net_device *netdev)
struct tap_nic * nic = netdev->priv;
struct pollfd pfd;
struct io_buffer * iobuf;
+ unsigned int quota = RX_QUOTA;
int r;
pfd.fd = nic->fd;
@@ -144,7 +146,8 @@ static void tap_poll(struct net_device *netdev)
if (! iobuf)
goto allocfail;
- while ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0) {
+ while (quota-- &&
+ ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0)) {
DBGC2(nic, "tap %p read %d bytes\n", nic, r);
iob_put(iobuf, r);