[PATCH 27/31] virtio: console: Add throttling support to prevent flooding ports

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Rogue processes on guests could pump in data to hosts and cause an OOM
condition on the host. The host can indicate when to stop and start
sending data via control messages.

Signed-off-by: Amit Shah <amit.shah@xxxxxxxxxx>
---
 drivers/char/virtio_console.c  |   21 ++++++++++++++++++++-
 include/linux/virtio_console.h |    1 +
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 4fefa4d..2409330 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -187,6 +187,9 @@ struct port {
 
 	/* We should allow only one process to open a port */
 	bool guest_connected;
+
+	/* Does the Host not want to accept more data currently?  */
+	bool host_throttled;
 };
 
 /* This is the very early arch-specified put chars function. */
@@ -540,6 +543,9 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
 
 	port = filp->private_data;
 
+	if (port->host_throttled)
+		return -ENOSPC;
+
 	return send_buf(port, ubuf, count, true);
 }
 
@@ -554,7 +560,7 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
 	ret = 0;
 	if (port->inbuf)
 		ret |= POLLIN | POLLRDNORM;
-	if (port->host_connected)
+	if (port->host_connected && !port->host_throttled)
 		ret |= POLLOUT;
 	if (!port->host_connected)
 		ret |= POLLHUP;
@@ -861,6 +867,18 @@ static void handle_control_message(struct ports_device *portdev,
 				err);
 
 		break;
+	case VIRTIO_CONSOLE_THROTTLE_PORT:
+		/*
+		 * Hosts can govern some policy to disallow rogue
+		 * guest processes writing indefinitely to ports
+		 * leading to OOM situations.  If we receive this
+		 * message here, it means the Host side of the port
+		 * either reached its max. limit to cache data or
+		 * signal to us that the host is ready to accept more
+		 * data.
+		 */
+		port->host_throttled = cpkt->value;
+		break;
 	}
 }
 
@@ -962,6 +980,7 @@ static int add_port(struct ports_device *portdev, u32 id)
 	port->cons.hvc = NULL;
 
 	port->host_connected = port->guest_connected = false;
+	port->host_throttled = false;
 
 	port->in_vq = portdev->in_vqs[port->id];
 	port->out_vq = portdev->out_vqs[port->id];
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
index 8e85045..4bd57c8 100644
--- a/include/linux/virtio_console.h
+++ b/include/linux/virtio_console.h
@@ -41,6 +41,7 @@ struct virtio_console_control {
 #define VIRTIO_CONSOLE_RESIZE		2
 #define VIRTIO_CONSOLE_PORT_OPEN	3
 #define VIRTIO_CONSOLE_PORT_NAME	4
+#define VIRTIO_CONSOLE_THROTTLE_PORT	5
 
 /*
  * This struct is put at the start of each data buffer that gets
-- 
1.6.2.5

_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/virtualization

[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux