All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue
@ 2017-03-28 16:46 Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 1/3] " Ladi Prosek
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ladi Prosek @ 2017-03-28 16:46 UTC (permalink / raw)
  To: virtualization; +Cc: arnd, mst

This series fixes issues with variable initialization in the virtio
balloon driver which manifest as the driver sending invalid memory
stats to the host.

v1->v2:

* Call update_balloon_stats instead of filling the buffer with
  invalid tags.
* Add BUG_ON to update_balloon_stats to formalize the invariant that
  all slots in the buffer must be initialized.

v2->v3:

* Remove BUG_ON and return the actual number of counters from
  update_balloon_stats instead.
* Added Arnd's patch to omit VM stats if CONFIG_VM_EVENT_COUNTERS
  is not defined.


Arnd Bergmann (1):
      virtio_balloon: prevent uninitialized variable use

Ladi Prosek (2):
      virtio_balloon: don't push uninitialized buffers to stats virtqueue
      virtio-balloon: use actual number of stats for stats queue buffers

 drivers/virtio/virtio_balloon.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Thanks!
Ladi

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue
  2017-03-28 16:46 [PATCH v3 0/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue Ladi Prosek
@ 2017-03-28 16:46 ` Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 3/3] virtio_balloon: prevent uninitialized variable use Ladi Prosek
  2 siblings, 0 replies; 5+ messages in thread
From: Ladi Prosek @ 2017-03-28 16:46 UTC (permalink / raw)
  To: virtualization; +Cc: arnd, mst

When init_vqs runs, virtio_balloon.stats is either uninitialized or
contains stale values. The host updates its state with garbage data
because it has no way of knowing that this is just a marker buffer
used for signaling.

This patch updates the stats before pushing the initial buffer.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
---
 drivers/virtio/virtio_balloon.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 4e11915..fcd06e1 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -429,6 +429,8 @@ static int init_vqs(struct virtio_balloon *vb)
 		 * Prime this virtqueue with one buffer so the hypervisor can
 		 * use it to signal us later (it can't be broken yet!).
 		 */
+		update_balloon_stats(vb);
+
 		sg_init_one(&sg, vb->stats, sizeof vb->stats);
 		if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
 		    < 0)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers
  2017-03-28 16:46 [PATCH v3 0/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 1/3] " Ladi Prosek
@ 2017-03-28 16:46 ` Ladi Prosek
  2017-03-28 20:33   ` Arnd Bergmann
  2017-03-28 16:46 ` [PATCH v3 3/3] virtio_balloon: prevent uninitialized variable use Ladi Prosek
  2 siblings, 1 reply; 5+ messages in thread
From: Ladi Prosek @ 2017-03-28 16:46 UTC (permalink / raw)
  To: virtualization; +Cc: arnd, mst

The virtio balloon driver contained a not-so-obvious invariant that
update_balloon_stats has to update exactly VIRTIO_BALLOON_S_NR counters
in order to send valid stats to the host. This commit fixes it by having
update_balloon_stats return the actual number of counters, and its
callers use it when pushing buffers to the stats virtqueue.

Note that it is still out of spec to change the number of counters
at run-time. "Driver MUST supply the same subset of statistics in all
buffers submitted to the statsq."

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
---
 drivers/virtio/virtio_balloon.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index fcd06e1..d9544db 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -242,11 +242,11 @@ static inline void update_stat(struct virtio_balloon *vb, int idx,
 
 #define pages_to_bytes(x) ((u64)(x) << PAGE_SHIFT)
 
-static void update_balloon_stats(struct virtio_balloon *vb)
+static unsigned int update_balloon_stats(struct virtio_balloon *vb)
 {
 	unsigned long events[NR_VM_EVENT_ITEMS];
 	struct sysinfo i;
-	int idx = 0;
+	unsigned int idx = 0;
 	long available;
 
 	all_vm_events(events);
@@ -266,6 +266,8 @@ static void update_balloon_stats(struct virtio_balloon *vb)
 				pages_to_bytes(i.totalram));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL,
 				pages_to_bytes(available));
+
+	return idx;
 }
 
 /*
@@ -291,14 +293,14 @@ static void stats_handle_request(struct virtio_balloon *vb)
 {
 	struct virtqueue *vq;
 	struct scatterlist sg;
-	unsigned int len;
+	unsigned int len, num_stats;
 
-	update_balloon_stats(vb);
+	num_stats = update_balloon_stats(vb);
 
 	vq = vb->stats_vq;
 	if (!virtqueue_get_buf(vq, &len))
 		return;
-	sg_init_one(&sg, vb->stats, sizeof(vb->stats));
+	sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
 	virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
 	virtqueue_kick(vq);
 }
@@ -423,15 +425,16 @@ static int init_vqs(struct virtio_balloon *vb)
 	vb->deflate_vq = vqs[1];
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
 		struct scatterlist sg;
+		unsigned int num_stats;
 		vb->stats_vq = vqs[2];
 
 		/*
 		 * Prime this virtqueue with one buffer so the hypervisor can
 		 * use it to signal us later (it can't be broken yet!).
 		 */
-		update_balloon_stats(vb);
+		num_stats = update_balloon_stats(vb);
 
-		sg_init_one(&sg, vb->stats, sizeof vb->stats);
+		sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
 		if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
 		    < 0)
 			BUG();
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/3] virtio_balloon: prevent uninitialized variable use
  2017-03-28 16:46 [PATCH v3 0/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 1/3] " Ladi Prosek
  2017-03-28 16:46 ` [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers Ladi Prosek
@ 2017-03-28 16:46 ` Ladi Prosek
  2 siblings, 0 replies; 5+ messages in thread
From: Ladi Prosek @ 2017-03-28 16:46 UTC (permalink / raw)
  To: virtualization; +Cc: arnd, mst

From: Arnd Bergmann <arnd@arndb.de>

The latest gcc-7.0.1 snapshot reports a new warning:

virtio/virtio_balloon.c: In function 'update_balloon_stats':
virtio/virtio_balloon.c:258:26: error: 'events[2]' is used uninitialized in this function [-Werror=uninitialized]
virtio/virtio_balloon.c:260:26: error: 'events[3]' is used uninitialized in this function [-Werror=uninitialized]
virtio/virtio_balloon.c:261:56: error: 'events[18]' is used uninitialized in this function [-Werror=uninitialized]
virtio/virtio_balloon.c:262:56: error: 'events[17]' is used uninitialized in this function [-Werror=uninitialized]

This seems absolutely right, so we should add an extra check to
prevent copying uninitialized stack data into the statistics.
From all I can tell, this has been broken since the statistics code
was originally added in 2.6.34.

Fixes: 9564e138b1f6 ("virtio: Add memory statistics reporting to the balloon driver (V4)")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
---
 drivers/virtio/virtio_balloon.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index d9544db..34adf9b 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -254,12 +254,14 @@ static unsigned int update_balloon_stats(struct virtio_balloon *vb)
 
 	available = si_mem_available();
 
+#ifdef CONFIG_VM_EVENT_COUNTERS
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
 				pages_to_bytes(events[PSWPIN]));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
 				pages_to_bytes(events[PSWPOUT]));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
+#endif
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
 				pages_to_bytes(i.freeram));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers
  2017-03-28 16:46 ` [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers Ladi Prosek
@ 2017-03-28 20:33   ` Arnd Bergmann
  0 siblings, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2017-03-28 20:33 UTC (permalink / raw)
  To: Ladi Prosek; +Cc: Michael S. Tsirkin, virtualization

On Tue, Mar 28, 2017 at 6:46 PM, Ladi Prosek <lprosek@redhat.com> wrote:
> The virtio balloon driver contained a not-so-obvious invariant that
> update_balloon_stats has to update exactly VIRTIO_BALLOON_S_NR counters
> in order to send valid stats to the host. This commit fixes it by having
> update_balloon_stats return the actual number of counters, and its
> callers use it when pushing buffers to the stats virtqueue.
>
> Note that it is still out of spec to change the number of counters
> at run-time. "Driver MUST supply the same subset of statistics in all
> buffers submitted to the statsq."
>
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Ladi Prosek <lprosek@redhat.com>

>
Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-03-28 20:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-28 16:46 [PATCH v3 0/3] virtio_balloon: don't push uninitialized buffers to stats virtqueue Ladi Prosek
2017-03-28 16:46 ` [PATCH v3 1/3] " Ladi Prosek
2017-03-28 16:46 ` [PATCH v3 2/3] virtio-balloon: use actual number of stats for stats queue buffers Ladi Prosek
2017-03-28 20:33   ` Arnd Bergmann
2017-03-28 16:46 ` [PATCH v3 3/3] virtio_balloon: prevent uninitialized variable use Ladi Prosek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.