raw/skeleton: fix segmentation fault on rawdev_autotest

Message ID 20181211131412.14232-1-hkalra@marvell.com (mailing list archive)
State Changes Requested, archived
Delegated to: Thomas Monjalon
Headers
Series raw/skeleton: fix segmentation fault on rawdev_autotest |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/mellanox-Performance-Testing success Performance Testing PASS
ci/intel-Performance-Testing success Performance Testing PASS

Commit Message

Harman Kalra Dec. 11, 2018, 1:14 p.m. UTC
  segmentation fault ocured as vdev->device.driver->name did not
return correct value.
Test2 failed as dummy_value was freed before it was used.

Signed-off-by: Kallio Marko <marko.kallio@cavium.comm>
Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 3 ++-
 drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)
  

Comments

Shreyansh Jain Dec. 13, 2018, 7:22 a.m. UTC | #1
On Tuesday 11 December 2018 06:44 PM, Harman Kalra wrote:
> segmentation fault ocured as vdev->device.driver->name did not
> return correct value.
> Test2 failed as dummy_value was freed before it was used.
> 
> Signed-off-by: Kallio Marko <marko.kallio@cavium.comm>
> Signed-off-by: Harman Kalra <hkalra@marvell.com>
> ---
>   drivers/raw/skeleton_rawdev/skeleton_rawdev.c      | 3 ++-
>   drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 4 ++--
>   2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> index d7630fc69..c957ced11 100644
> --- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> @@ -585,7 +585,8 @@ skeleton_rawdev_create(const char *name,
>   
>   	rawdev->dev_ops = &skeleton_rawdev_ops;
>   	rawdev->device = &vdev->device;
> -	rawdev->driver_name = vdev->device.driver->name;
> +
> +	rawdev->driver_name = rawdev->name;

This is not right. rawdev->name is name of the device and not that of a 
driver.

But, this also highlights a much bigger issue here:

----
$ master+* ± grep driver_name * -rn
dpaa2_cmdif/dpaa2_cmdif.c:214:  rawdev->driver_name = 
vdev->device.driver->name;
dpaa2_qdma/dpaa2_qdma.c:958:    rawdev->driver_name = 
dpaa2_drv->driver.name;
ifpga_rawdev/ifpga_rawdev.c:421:        rawdev->driver_name = 
pci_dev->device.driver->name;
skeleton_rawdev/skeleton_rawdev.c:588:  rawdev->driver_name = 
vdev->device.driver->name;
----

So, it seems that all rawdev drivers are assuming that even before probe 
is over (this assignment is path of probe within driver), they can 
assign the name to the 'device.driver'.

Here is the snippet from bus/pci/pci_common.c
--->8---
         ret = dr->probe(dr, dev);
	...
         if (ret) {
		/* Error case */
		...
         } else {
                 dev->device.driver = &dr->driver;
         }
--->8---

And from bus/vdev/vdev.c

--->8---
         ret = driver->probe(dev);
         if (ret == 0)
                 dev->device.driver = &driver->driver;
--->8---

So, the bus is actually assigning device.driver part *after* probe is 
successfully complete.

So, if your's segfaulted, there is a high probability others too would 
encounter the same.
This needs investigation.



>   
>   	skeldev = skeleton_rawdev_get_priv(rawdev);
>   
> diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> index 359c9e296..788c3f1b9 100644
> --- a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> @@ -294,14 +294,14 @@ test_rawdev_attr_set_get(void)
>   			      "Attribute (Test1) not set correctly (%" PRIu64 ")",
>   			      ret_value);
>   
> -	free(dummy_value);
> -
>   	ret_value = 0;
>   	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
>   	RTE_TEST_ASSERT_EQUAL(*((int *)(uintptr_t)ret_value), 200,
>   			      "Attribute (Test2) not set correctly (%" PRIu64 ")",
>   			      ret_value);
>   
> +	free(dummy_value);
> +

The issue that you report is correct - that dummy_value is being 
released before next test - causing segfault.

The problem here is that if free(dummy_value) is called *after* "Test2", 
coverity reports error [See: 88d0e47880ec ("raw/skeleton: fix memory 
leak on test failure"] - and rightly so because RTE_TES_ASSERT_EQUAL() 
returns in case of error.

I will try and find a way out of this.

>   	return TEST_SUCCESS;
>   }
>   
>
  

Patch

diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
index d7630fc69..c957ced11 100644
--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
@@ -585,7 +585,8 @@  skeleton_rawdev_create(const char *name,
 
 	rawdev->dev_ops = &skeleton_rawdev_ops;
 	rawdev->device = &vdev->device;
-	rawdev->driver_name = vdev->device.driver->name;
+
+	rawdev->driver_name = rawdev->name;
 
 	skeldev = skeleton_rawdev_get_priv(rawdev);
 
diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
index 359c9e296..788c3f1b9 100644
--- a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
+++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
@@ -294,14 +294,14 @@  test_rawdev_attr_set_get(void)
 			      "Attribute (Test1) not set correctly (%" PRIu64 ")",
 			      ret_value);
 
-	free(dummy_value);
-
 	ret_value = 0;
 	ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
 	RTE_TEST_ASSERT_EQUAL(*((int *)(uintptr_t)ret_value), 200,
 			      "Attribute (Test2) not set correctly (%" PRIu64 ")",
 			      ret_value);
 
+	free(dummy_value);
+
 	return TEST_SUCCESS;
 }