[x/azure, c/azure][PATCH v2 0/2] Include upstream vmbus fixes to linux-azure

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[x/azure, c/azure][PATCH v2 0/2] Include upstream vmbus fixes to linux-azure

Marcelo Henrique Cerri
BugLink: http://bugs.launchpad.net/bugs/1821378

On v1 I had wrongly formatted the xenial patches using the cosmic branch.

Dexuan Cui (2):
  Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened
    channels
  Drivers: hv: vmbus: Check for ring when getting debug info

 drivers/hv/ring_buffer.c | 31 +++++++++---------
 drivers/hv/vmbus_drv.c   | 71 ++++++++++++++++++++++++++++++++++------
 include/linux/hyperv.h   |  5 +--
 3 files changed, 79 insertions(+), 28 deletions(-)

--
2.20.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[x/azure][PATCH v2 1/2] Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels

Marcelo Henrique Cerri
From: Dexuan Cui <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1821378

Before 98f4c651762c, we returned zeros for unopened channels.
With 98f4c651762c, we started to return random on-stack values.

We'd better return -EINVAL instead.

Fixes: 98f4c651762c ("hv: move ringbuffer bus attributes to dev_groups")
Cc: [hidden email]
Cc: K. Y. Srinivasan <[hidden email]>
Cc: Haiyang Zhang <[hidden email]>
Cc: Stephen Hemminger <[hidden email]>
Signed-off-by: Dexuan Cui <[hidden email]>
Signed-off-by: Sasha Levin <[hidden email]>
(cherry picked from commit fc96df16a1ce80cbb3c316ab7d4dc8cd5c2852ce)
Signed-off-by: Marcelo Henrique Cerri <[hidden email]>
---
 drivers/hv/vmbus_drv.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 67bf45a69f1b..f6b6d5d59d85 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -300,6 +300,8 @@ static ssize_t out_intr_mask_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
 }
@@ -313,6 +315,8 @@ static ssize_t out_read_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_read_index);
 }
@@ -327,6 +331,8 @@ static ssize_t out_write_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_write_index);
 }
@@ -341,6 +347,8 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
 }
@@ -355,6 +363,8 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
 }
@@ -368,6 +378,8 @@ static ssize_t in_intr_mask_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
 }
@@ -381,6 +393,8 @@ static ssize_t in_read_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_read_index);
 }
@@ -394,6 +408,8 @@ static ssize_t in_write_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_write_index);
 }
@@ -408,6 +424,8 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
 }
@@ -422,6 +440,8 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
 }
--
2.20.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[x/azure][PATCH v2 2/2] Drivers: hv: vmbus: Check for ring when getting debug info

Marcelo Henrique Cerri
In reply to this post by Marcelo Henrique Cerri
From: Dexuan Cui <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1821378

fc96df16a1ce is good and can already fix the "return stack garbage" issue,
but let's also improve hv_ringbuffer_get_debuginfo(), which would silently
return stack garbage, if people forget to check channel->state or
ring_info->ring_buffer, when using the function in the future.

Having an error check in the function would eliminate the potential risk.

Add a Fixes tag to indicate the patch depdendency.

Fixes: fc96df16a1ce ("Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels")
Cc: [hidden email]
Cc: K. Y. Srinivasan <[hidden email]>
Cc: Haiyang Zhang <[hidden email]>
Signed-off-by: Stephen Hemminger <[hidden email]>
Signed-off-by: Dexuan Cui <[hidden email]>
Signed-off-by: Sasha Levin <[hidden email]>
(cherry picked from commit ba50bf1ce9a51fc97db58b96d01306aa70bc3979)
Signed-off-by: Marcelo Henrique Cerri <[hidden email]>
---
 drivers/hv/ring_buffer.c | 31 +++++++-------
 drivers/hv/vmbus_drv.c   | 91 +++++++++++++++++++++++++++-------------
 include/linux/hyperv.h   |  5 ++-
 3 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 3f8dde8d59ba..74c1dfb8183b 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -141,26 +141,25 @@ static u32 hv_copyto_ringbuffer(
 }
 
 /* Get various debug metrics for the specified ring buffer. */
-void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
- struct hv_ring_buffer_debug_info *debug_info)
+int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+ struct hv_ring_buffer_debug_info *debug_info)
 {
  u32 bytes_avail_towrite;
  u32 bytes_avail_toread;
 
- if (ring_info->ring_buffer) {
- hv_get_ringbuffer_availbytes(ring_info,
- &bytes_avail_toread,
- &bytes_avail_towrite);
-
- debug_info->bytes_avail_toread = bytes_avail_toread;
- debug_info->bytes_avail_towrite = bytes_avail_towrite;
- debug_info->current_read_index =
- ring_info->ring_buffer->read_index;
- debug_info->current_write_index =
- ring_info->ring_buffer->write_index;
- debug_info->current_interrupt_mask =
- ring_info->ring_buffer->interrupt_mask;
- }
+ if (!ring_info->ring_buffer)
+ return -EINVAL;
+
+ hv_get_ringbuffer_availbytes(ring_info,
+     &bytes_avail_toread,
+     &bytes_avail_towrite);
+ debug_info->bytes_avail_toread = bytes_avail_toread;
+ debug_info->bytes_avail_towrite = bytes_avail_towrite;
+ debug_info->current_read_index = ring_info->ring_buffer->read_index;
+ debug_info->current_write_index = ring_info->ring_buffer->write_index;
+ debug_info->current_interrupt_mask
+ = ring_info->ring_buffer->interrupt_mask;
+ return 0;
 }
 EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo);
 
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f6b6d5d59d85..f699d5777c78 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -297,12 +297,16 @@ static ssize_t out_intr_mask_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
 }
 static DEVICE_ATTR_RO(out_intr_mask);
@@ -312,12 +316,15 @@ static ssize_t out_read_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.current_read_index);
 }
 static DEVICE_ATTR_RO(out_read_index);
@@ -328,12 +335,15 @@ static ssize_t out_write_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.current_write_index);
 }
 static DEVICE_ATTR_RO(out_write_index);
@@ -344,12 +354,15 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
 }
 static DEVICE_ATTR_RO(out_read_bytes_avail);
@@ -360,12 +373,15 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
 }
 static DEVICE_ATTR_RO(out_write_bytes_avail);
@@ -375,12 +391,15 @@ static ssize_t in_intr_mask_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
 }
 static DEVICE_ATTR_RO(in_intr_mask);
@@ -390,12 +409,15 @@ static ssize_t in_read_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_read_index);
 }
 static DEVICE_ATTR_RO(in_read_index);
@@ -405,12 +427,15 @@ static ssize_t in_write_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_write_index);
 }
 static DEVICE_ATTR_RO(in_write_index);
@@ -421,12 +446,15 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
 }
 static DEVICE_ATTR_RO(in_read_bytes_avail);
@@ -437,12 +465,15 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
 }
 static DEVICE_ATTR_RO(in_write_bytes_avail);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index d5ce3eeeb556..5f11b715e075 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1137,8 +1137,9 @@ struct hv_ring_buffer_debug_info {
  u32 bytes_avail_towrite;
 };
 
-void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
-    struct hv_ring_buffer_debug_info *debug_info);
+
+int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+ struct hv_ring_buffer_debug_info *debug_info);
 
 /* Vmbus interface */
 #define vmbus_driver_register(driver) \
--
2.20.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[c/azure][PATCH v2 3/4] Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels

Marcelo Henrique Cerri
In reply to this post by Marcelo Henrique Cerri
From: Dexuan Cui <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1821378

Before 98f4c651762c, we returned zeros for unopened channels.
With 98f4c651762c, we started to return random on-stack values.

We'd better return -EINVAL instead.

Fixes: 98f4c651762c ("hv: move ringbuffer bus attributes to dev_groups")
Cc: [hidden email]
Cc: K. Y. Srinivasan <[hidden email]>
Cc: Haiyang Zhang <[hidden email]>
Cc: Stephen Hemminger <[hidden email]>
Signed-off-by: Dexuan Cui <[hidden email]>
Signed-off-by: Sasha Levin <[hidden email]>
(cherry picked from commit fc96df16a1ce80cbb3c316ab7d4dc8cd5c2852ce)
Signed-off-by: Marcelo Henrique Cerri <[hidden email]>
---
 drivers/hv/vmbus_drv.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 28c6f00d9d2c..dff1b632eb56 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -300,6 +300,8 @@ static ssize_t out_intr_mask_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
 }
@@ -313,6 +315,8 @@ static ssize_t out_read_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_read_index);
 }
@@ -327,6 +331,8 @@ static ssize_t out_write_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.current_write_index);
 }
@@ -341,6 +347,8 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
 }
@@ -355,6 +363,8 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
  return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
 }
@@ -368,6 +378,8 @@ static ssize_t in_intr_mask_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
 }
@@ -381,6 +393,8 @@ static ssize_t in_read_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_read_index);
 }
@@ -394,6 +408,8 @@ static ssize_t in_write_index_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.current_write_index);
 }
@@ -408,6 +424,8 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
 }
@@ -422,6 +440,8 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
 
  if (!hv_dev->channel)
  return -ENODEV;
+ if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
+ return -EINVAL;
  hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
  return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
 }
--
2.20.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[c/azure][PATCH v2 4/4] Drivers: hv: vmbus: Check for ring when getting debug info

Marcelo Henrique Cerri
In reply to this post by Marcelo Henrique Cerri
From: Dexuan Cui <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1821378

fc96df16a1ce is good and can already fix the "return stack garbage" issue,
but let's also improve hv_ringbuffer_get_debuginfo(), which would silently
return stack garbage, if people forget to check channel->state or
ring_info->ring_buffer, when using the function in the future.

Having an error check in the function would eliminate the potential risk.

Add a Fixes tag to indicate the patch depdendency.

Fixes: fc96df16a1ce ("Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels")
Cc: [hidden email]
Cc: K. Y. Srinivasan <[hidden email]>
Cc: Haiyang Zhang <[hidden email]>
Signed-off-by: Stephen Hemminger <[hidden email]>
Signed-off-by: Dexuan Cui <[hidden email]>
Signed-off-by: Sasha Levin <[hidden email]>
(cherry picked from commit ba50bf1ce9a51fc97db58b96d01306aa70bc3979)
Signed-off-by: Marcelo Henrique Cerri <[hidden email]>
---
 drivers/hv/ring_buffer.c | 31 +++++++-------
 drivers/hv/vmbus_drv.c   | 91 +++++++++++++++++++++++++++-------------
 include/linux/hyperv.h   |  5 ++-
 3 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 240774e2bc2e..e67ccb108d67 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -164,26 +164,25 @@ hv_get_ringbuffer_availbytes(const struct hv_ring_buffer_info *rbi,
 }
 
 /* Get various debug metrics for the specified ring buffer. */
-void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
- struct hv_ring_buffer_debug_info *debug_info)
+int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+ struct hv_ring_buffer_debug_info *debug_info)
 {
  u32 bytes_avail_towrite;
  u32 bytes_avail_toread;
 
- if (ring_info->ring_buffer) {
- hv_get_ringbuffer_availbytes(ring_info,
- &bytes_avail_toread,
- &bytes_avail_towrite);
-
- debug_info->bytes_avail_toread = bytes_avail_toread;
- debug_info->bytes_avail_towrite = bytes_avail_towrite;
- debug_info->current_read_index =
- ring_info->ring_buffer->read_index;
- debug_info->current_write_index =
- ring_info->ring_buffer->write_index;
- debug_info->current_interrupt_mask =
- ring_info->ring_buffer->interrupt_mask;
- }
+ if (!ring_info->ring_buffer)
+ return -EINVAL;
+
+ hv_get_ringbuffer_availbytes(ring_info,
+     &bytes_avail_toread,
+     &bytes_avail_towrite);
+ debug_info->bytes_avail_toread = bytes_avail_toread;
+ debug_info->bytes_avail_towrite = bytes_avail_towrite;
+ debug_info->current_read_index = ring_info->ring_buffer->read_index;
+ debug_info->current_write_index = ring_info->ring_buffer->write_index;
+ debug_info->current_interrupt_mask
+ = ring_info->ring_buffer->interrupt_mask;
+ return 0;
 }
 EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo);
 
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index dff1b632eb56..10c4070a009e 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -297,12 +297,16 @@ static ssize_t out_intr_mask_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
 }
 static DEVICE_ATTR_RO(out_intr_mask);
@@ -312,12 +316,15 @@ static ssize_t out_read_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.current_read_index);
 }
 static DEVICE_ATTR_RO(out_read_index);
@@ -328,12 +335,15 @@ static ssize_t out_write_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.current_write_index);
 }
 static DEVICE_ATTR_RO(out_write_index);
@@ -344,12 +354,15 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
 }
 static DEVICE_ATTR_RO(out_read_bytes_avail);
@@ -360,12 +373,15 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info outbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
+  &outbound);
+ if (ret < 0)
+ return ret;
  return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
 }
 static DEVICE_ATTR_RO(out_write_bytes_avail);
@@ -375,12 +391,15 @@ static ssize_t in_intr_mask_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
 }
 static DEVICE_ATTR_RO(in_intr_mask);
@@ -390,12 +409,15 @@ static ssize_t in_read_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_read_index);
 }
 static DEVICE_ATTR_RO(in_read_index);
@@ -405,12 +427,15 @@ static ssize_t in_write_index_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.current_write_index);
 }
 static DEVICE_ATTR_RO(in_write_index);
@@ -421,12 +446,15 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
 }
 static DEVICE_ATTR_RO(in_read_bytes_avail);
@@ -437,12 +465,15 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
 {
  struct hv_device *hv_dev = device_to_hv_device(dev);
  struct hv_ring_buffer_debug_info inbound;
+ int ret;
 
  if (!hv_dev->channel)
  return -ENODEV;
- if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
- return -EINVAL;
- hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+
+ ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
+ if (ret < 0)
+ return ret;
+
  return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
 }
 static DEVICE_ATTR_RO(in_write_bytes_avail);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 89d09b4064a4..2086908b2c8c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1160,8 +1160,9 @@ struct hv_ring_buffer_debug_info {
  u32 bytes_avail_towrite;
 };
 
-void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
-    struct hv_ring_buffer_debug_info *debug_info);
+
+int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
+ struct hv_ring_buffer_debug_info *debug_info);
 
 /* Vmbus interface */
 #define vmbus_driver_register(driver) \
--
2.20.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [x/azure, c/azure][PATCH v2 0/2] Include upstream vmbus fixes to linux-azure

Stefan Bader-2
In reply to this post by Marcelo Henrique Cerri
On 22.04.19 22:29, Marcelo Henrique Cerri wrote:

> BugLink: http://bugs.launchpad.net/bugs/1821378
>
> On v1 I had wrongly formatted the xenial patches using the cosmic branch.
>
> Dexuan Cui (2):
>   Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened
>     channels
>   Drivers: hv: vmbus: Check for ring when getting debug info
>
>  drivers/hv/ring_buffer.c | 31 +++++++++---------
>  drivers/hv/vmbus_drv.c   | 71 ++++++++++++++++++++++++++++++++++------
>  include/linux/hyperv.h   |  5 +--
>  3 files changed, 79 insertions(+), 28 deletions(-)
>
Acked-by: Stefan Bader <[hidden email]>


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

ACK: [x/azure, c/azure][PATCH v2 0/2] Include upstream vmbus fixes to linux-azure

Kleber Souza
In reply to this post by Marcelo Henrique Cerri
On 4/22/19 10:29 PM, Marcelo Henrique Cerri wrote:

> BugLink: http://bugs.launchpad.net/bugs/1821378
>
> On v1 I had wrongly formatted the xenial patches using the cosmic branch.
>
> Dexuan Cui (2):
>   Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened
>     channels
>   Drivers: hv: vmbus: Check for ring when getting debug info
>
>  drivers/hv/ring_buffer.c | 31 +++++++++---------
>  drivers/hv/vmbus_drv.c   | 71 ++++++++++++++++++++++++++++++++++------
>  include/linux/hyperv.h   |  5 +--
>  3 files changed, 79 insertions(+), 28 deletions(-)
>

Acked-by: Kleber Sacilotto de Souza <[hidden email]>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED: [x/azure,c/azure][PATCH v2 0/2] Include upstream vmbus fixes to linux-azure

Marcelo Henrique Cerri
In reply to this post by Marcelo Henrique Cerri
--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (499 bytes) Download Attachment