diff mbox series

[ovs-dev,v2] dynamic-string: fix a crash in ds_clone()

Message ID 20210812063333.73171-1-sriharsha.basavapatna@broadcom.com
State Accepted
Headers show
Series [ovs-dev,v2] dynamic-string: fix a crash in ds_clone() | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

Sriharsha Basavapatna Aug. 12, 2021, 6:33 a.m. UTC
In netdev_offload_dpdk_flow_create() when an offload request fails,
dump_flow() is called to log a warning message. The 's_tnl' string
in flow_patterns gets initialized in vport_to_rte_tunnel() conditionally
via ds_put_format(). If it is not initialized, it crashes later in
dump_flow_attr()->ds_clone()->memcpy() while dereferencing this string.

To fix this, check if memory for the src string has been allocated,
before copying it to the dst string.

Fixes: fa44a4a3ff7b ("ovn-controller: Persist desired conntrack groups.")
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>

---

v1->v2: fix ds_clone(); ds_cstr() not needed in callers.

---

 lib/dynamic-string.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Ilya Maximets Aug. 12, 2021, 10:37 p.m. UTC | #1
On 8/12/21 8:33 AM, Sriharsha Basavapatna via dev wrote:
> In netdev_offload_dpdk_flow_create() when an offload request fails,
> dump_flow() is called to log a warning message. The 's_tnl' string
> in flow_patterns gets initialized in vport_to_rte_tunnel() conditionally
> via ds_put_format(). If it is not initialized, it crashes later in
> dump_flow_attr()->ds_clone()->memcpy() while dereferencing this string.
> 
> To fix this, check if memory for the src string has been allocated,
> before copying it to the dst string.
> 
> Fixes: fa44a4a3ff7b ("ovn-controller: Persist desired conntrack groups.")
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> 
> ---
> 
> v1->v2: fix ds_clone(); ds_cstr() not needed in callers.

Thanks!  This version looks good to me.  I'd add a few more generic
words to the commit message, so it will be easier to understand the
change on older branches, but I can do that before applying the patch.

There supposed to be a separate patch for correct initialization of
s_tnl in the lib/netdev-offload-dpdk.c, as Gaetan suggested.  We need
to initialize them with DS_EMPTY_INITIALIZER.  Though it will not be
different from the actual memory initialization point of view, it's
a more correct way to work with dynamic string.  Something like this:

@@ -1324,7 +1325,11 @@ netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns,
                              struct netdev *netdev,
                              uint32_t flow_mark)
 {
-    struct flow_actions actions = { .actions = NULL, .cnt = 0 };
+    struct flow_actions actions = {
+        .actions = NULL,
+        .cnt = 0,
+        .s_tnl = DS_EMPTY_INITIALIZER,
+    };
     const struct rte_flow_attr flow_attr = {
         .group = 0,
         .priority = 0,
---

And the same for other initializations of 'struct flow_actions' and
'struct flow_patterns'.  I also noticed that free_flow_patterns()
doesn't destroy the s_tnl, i.e. leaks it.  This can be fixed in the
same patch along with correct initialization.

Could you prepare this kind of patch?

Best regards, Ilya Maximets.
Sriharsha Basavapatna Aug. 13, 2021, 2:39 a.m. UTC | #2
On Fri, Aug 13, 2021 at 4:07 AM Ilya Maximets <i.maximets@ovn.org> wrote:
>
> On 8/12/21 8:33 AM, Sriharsha Basavapatna via dev wrote:
> > In netdev_offload_dpdk_flow_create() when an offload request fails,
> > dump_flow() is called to log a warning message. The 's_tnl' string
> > in flow_patterns gets initialized in vport_to_rte_tunnel() conditionally
> > via ds_put_format(). If it is not initialized, it crashes later in
> > dump_flow_attr()->ds_clone()->memcpy() while dereferencing this string.
> >
> > To fix this, check if memory for the src string has been allocated,
> > before copying it to the dst string.
> >
> > Fixes: fa44a4a3ff7b ("ovn-controller: Persist desired conntrack groups.")
> > Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> >
> > ---
> >
> > v1->v2: fix ds_clone(); ds_cstr() not needed in callers.
>
> Thanks!  This version looks good to me.  I'd add a few more generic
> words to the commit message, so it will be easier to understand the
> change on older branches, but I can do that before applying the patch.

Yes, please feel free to update the commit message, thanks !
>
> There supposed to be a separate patch for correct initialization of
> s_tnl in the lib/netdev-offload-dpdk.c, as Gaetan suggested.  We need
> to initialize them with DS_EMPTY_INITIALIZER.  Though it will not be
> different from the actual memory initialization point of view, it's
> a more correct way to work with dynamic string.  Something like this:
>
> @@ -1324,7 +1325,11 @@ netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns,
>                               struct netdev *netdev,
>                               uint32_t flow_mark)
>  {
> -    struct flow_actions actions = { .actions = NULL, .cnt = 0 };
> +    struct flow_actions actions = {
> +        .actions = NULL,
> +        .cnt = 0,
> +        .s_tnl = DS_EMPTY_INITIALIZER,
> +    };
>      const struct rte_flow_attr flow_attr = {
>          .group = 0,
>          .priority = 0,
> ---
>
> And the same for other initializations of 'struct flow_actions' and
> 'struct flow_patterns'.  I also noticed that free_flow_patterns()
> doesn't destroy the s_tnl, i.e. leaks it.  This can be fixed in the
> same patch along with correct initialization.
>
> Could you prepare this kind of patch?

Sure, I'll send out a separate patch for this.

Thanks,
-Harsha
>
> Best regards, Ilya Maximets.
Ilya Maximets Aug. 16, 2021, 8:04 p.m. UTC | #3
On 8/13/21 4:39 AM, Sriharsha Basavapatna via dev wrote:
> On Fri, Aug 13, 2021 at 4:07 AM Ilya Maximets <i.maximets@ovn.org> wrote:
>>
>> On 8/12/21 8:33 AM, Sriharsha Basavapatna via dev wrote:
>>> In netdev_offload_dpdk_flow_create() when an offload request fails,
>>> dump_flow() is called to log a warning message. The 's_tnl' string
>>> in flow_patterns gets initialized in vport_to_rte_tunnel() conditionally
>>> via ds_put_format(). If it is not initialized, it crashes later in
>>> dump_flow_attr()->ds_clone()->memcpy() while dereferencing this string.
>>>
>>> To fix this, check if memory for the src string has been allocated,
>>> before copying it to the dst string.
>>>
>>> Fixes: fa44a4a3ff7b ("ovn-controller: Persist desired conntrack groups.")
>>> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
>>>
>>> ---
>>>
>>> v1->v2: fix ds_clone(); ds_cstr() not needed in callers.
>>
>> Thanks!  This version looks good to me.  I'd add a few more generic
>> words to the commit message, so it will be easier to understand the
>> change on older branches, but I can do that before applying the patch.
> 
> Yes, please feel free to update the commit message, thanks !

Thanks!  Applied to master and backported down to 2.12.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/lib/dynamic-string.c b/lib/dynamic-string.c
index 6f7b610a9..fd0127ed1 100644
--- a/lib/dynamic-string.c
+++ b/lib/dynamic-string.c
@@ -460,6 +460,10 @@  ds_chomp(struct ds *ds, int c)
 void
 ds_clone(struct ds *dst, struct ds *source)
 {
+    if (!source->allocated) {
+        ds_init(dst);
+        return;
+    }
     dst->length = source->length;
     dst->allocated = dst->length;
     dst->string = xmalloc(dst->allocated + 1);