From: Aaron Conole <aconole@redhat.com>
To: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: David Marchand <david.marchand@redhat.com>,
Bernard Iremonger <bernard.iremonger@intel.com>,
dev <dev@dpdk.org>, dpdk stable <stable@dpdk.org>,
Thomas Monjalon <thomas@monjalon.net>, "Singh\,
Jasvinder" <jasvinder.singh@intel.com>,
Flavia Musatescu <flavia.musatescu@intel.com>,
Adrien Mazarguil <adrien.mazarguil@6wind.com>
Subject: Re: [dpdk-dev] [dpdk-stable] [PATCH] librte_flow_classify: fix out-of-bounds access
Date: Tue, 30 Jul 2019 13:30:19 -0400 [thread overview]
Message-ID: <f7ta7cvl9as.fsf@dhcp-25.97.bos.redhat.com> (raw)
In-Reply-To: <f484bced-34d8-7258-4927-1717f363b6c6@intel.com> (Ferruh Yigit's message of "Tue, 30 Jul 2019 17:55:20 +0100")
Ferruh Yigit <ferruh.yigit@intel.com> writes:
> On 7/30/2019 4:43 PM, Aaron Conole wrote:
>> Ferruh Yigit <ferruh.yigit@intel.com> writes:
>>
>>> On 7/30/2019 3:42 PM, Aaron Conole wrote:
>>>> David Marchand <david.marchand@redhat.com> writes:
>>>>
>>>>> On Wed, Jul 10, 2019 at 11:49 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>>>>>>
>>>>>> 09/07/2019 13:09, Bernard Iremonger:
>>>>>>> This patch fixes the out-of-bounds coverity issue by removing the
>>>>>>> offending line of code at line 107 in rte_flow_classify_parse.c
>>>>>>> which is never executed.
>>>>>>>
>>>>>>> Coverity issue: 343454
>>>>>>>
>>>>>>> Fixes: be41ac2a330f ("flow_classify: introduce flow classify library")
>>>>>>> Cc: stable@dpdk.org
>>>>>>> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
>>>>>>
>>>>>> Applied, thanks
>>>>>
>>>>> We have a segfault in the unit tests since this patch.
>>>>
>>>> I think this patch is still correct. The issue is in the semantic of
>>>> the flow classify pattern. It *MUST* always have a valid end marker,
>>>> but the test passes an invalid end marker. This causes the bounds to
>>>> exceed.
>>>>
>>>> So, it would be best to fix it, either by having a "failure" on unknown
>>>> markers (f.e. -1), or by passing a length around. However, the crash
>>>> should be expected. The fact that the previous code was also incorrect
>>>> and resulted in no segfault is pure luck.
>>>>
>>>> See rte_flow_classify_parse.c:80 and test_flow_classify.c:387
>>>>
>>>> I would be in favor of passing the lengths of the two arrays to these
>>>> APIs. That would let us still make use of the markers (for valid
>>>> construction), but also let us reason about lengths in a sane way.
>>>>
>>>> WDYT?
>>>>
>>>
>>> +1, I also just replied with something very similar.
>>>
>>> With current API the testcase is wrong, and it will crash, also the invalid
>>> action one has exact same problem.
>>>
>>> The API can be updated as you suggested, with a length field and testcases can
>>> be added back.
>>>
>>> What worries me more is the rte_flow, which uses same arguments, and open to
>>> same errors, should we consider updating rte_flow APIs to have lengths values too?
>>
>> Probably.
>>
>> Here's a first crack at the change I think is appropriate. I have done
>> some limited testing. Let me know if you want me to submit it formally.
>>
>> ---------------------------- 8< ---------------------------------
>> Subject: [PATCH] rte_flow_classify: fix up the API and preserve ABI
>>
>> Introduces a new API for doing length validations, and preserves the old semantics
>> and API. The previous API couldn't handle corrupted end markers. A future
>> version of the API might be able to eschew the end marker and trust the length,
>> but that is a discussion for future.
>>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>> app/test/test_flow_classify.c | 30 +-------
>> lib/librte_flow_classify/rte_flow_classify.c | 72 +++++++++++++++++---
>> lib/librte_flow_classify/rte_flow_classify.h | 28 ++++++++
>> 3 files changed, 91 insertions(+), 39 deletions(-)
>>
>> diff --git a/app/test/test_flow_classify.c b/app/test/test_flow_classify.c
>> index 6bbaad364..ff5265c6a 100644
>> --- a/app/test/test_flow_classify.c
>> +++ b/app/test/test_flow_classify.c
>> @@ -125,7 +125,6 @@ static struct rte_flow_item udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,
>>
>> static struct rte_flow_item end_item = { RTE_FLOW_ITEM_TYPE_END,
>> 0, 0, 0 };
>> -static struct rte_flow_item end_item_bad = { -1, 0, 0, 0 };
>>
>> /* test TCP pattern:
>> * "eth / ipv4 src spec 1.2.3.4 src mask 255.255.255.00 dst spec 5.6.7.8
>> @@ -181,7 +180,6 @@ static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
>> static struct rte_flow_action count_action_bad = { -1, 0};
>>
>> static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
>> -static struct rte_flow_action end_action_bad = { -1, 0};
>>
>> static struct rte_flow_action actions[2];
>>
>> @@ -384,7 +382,7 @@ test_invalid_patterns(void)
>>
>> pattern[1] = ipv4_udp_item_1;
>> pattern[2] = udp_item_bad;
>> - pattern[3] = end_item_bad;
>> + pattern[3] = end_item;
>>
>> ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
>> actions, &error);
>> @@ -458,32 +456,6 @@ test_invalid_actions(void)
>> return -1;
>> }
>>
>> - actions[0] = count_action;
>> - actions[1] = end_action_bad;
>> -
>> - ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
>> - actions, &error);
>> - if (!ret) {
>> - printf("Line %i: rte_flow_classify_validate", __LINE__);
>> - printf(" should have failed!\n");
>> - return -1;
>> - }
>> -
>> - rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
>> - actions, &key_found, &error);
>> - if (rule) {
>> - printf("Line %i: flow_classify_table_entry_add", __LINE__);
>> - printf(" should have failed!\n");
>> - return -1;
>> - }
>> -
>> - ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
>> - if (!ret) {
>> - printf("Line %i: rte_flow_classify_table_entry_delete",
>> - __LINE__);
>> - printf("should have failed!\n");
>> - return -1;
>> - }
>> return 0;
>> }
>
> +1 to unit test updates, lgtm.
>
> And I am for pushing the library updates to the next release, but please find a
> few comments for now.
Okay - I'll do that. But we probably will need to note that these APIs
should get deprecated. Not sure if that should happen in this release -
as the author of most of the code, maybe you would take care of that
part? :)
>
>>
>> diff --git a/lib/librte_flow_classify/rte_flow_classify.c b/lib/librte_flow_classify/rte_flow_classify.c
>> index 5ff585803..3ca1b1b44 100644
>> --- a/lib/librte_flow_classify/rte_flow_classify.c
>> +++ b/lib/librte_flow_classify/rte_flow_classify.c
>> @@ -89,18 +89,51 @@ struct rte_flow_classify_rule {
>> void *entry_ptr; /* handle to the table entry for rule meta data */
>> };
>>
>> +static size_t
>> +calc_flow_item_alen(const struct rte_flow_item pattern[])
>> +{
>> + size_t i = 0;
>> + while (pattern && (pattern + i)->type != RTE_FLOW_ITEM_TYPE_END)
>> + i++;
>> + return i + 1;
>
> I think better to send '0' if the pointer is NULL, (instead of 1)
Okay. Makes sense.
> <...>
>
>> @@ -186,6 +186,34 @@ int
>> rte_flow_classify_table_create(struct rte_flow_classifier *cls,
>> struct rte_flow_classify_table_params *params);
>>
>> +/**
>> + * Flow classify validate
>> + *
>> + * @param cls
>> + * Handle to flow classifier instance
>> + * @param[in] attr
>> + * Flow rule attributes
>> + * @param[in] pattern
>> + * Pattern specification (list terminated by the END pattern item).
>> + * @param[in] actions
>> + * Associated actions (list terminated by the END pattern item).
>> + * @param[out] error
>> + * Perform verbose error reporting if not NULL. Structure
>> + * initialised in case of error only.
>> + * @return
>> + * 0 on success, error code otherwise
>> + */
>> +__rte_experimental
>> +int
>> +rte_flow_classify_validate_l(struct rte_flow_classifier *cls,
>> + const struct rte_flow_attr *attr,
>> + const struct rte_flow_item pattern[],
>> + const size_t pattern_l,
>> + const struct rte_flow_action actions[],
>> + const size_t actions_l,
>> + struct rte_flow_error *error);
>
> The doxygen comment is missing for 'pattern_l' & 'actions_l' but from code it is
> number of items in the lists, this is duplication of the END marker information.
> Instead, if those lengths are the length of the arrays will it be easier for the
> user? So user won't need to calculate the item count but can pass the size of
> the array. This still prevents API access out of the array.
>
> Anyway, as suggested above lets not make these decisions just a few days before
> the release, but just get the unit test fix for the release, does it make sense?
Sure.
> And if so, can you send the unit test patch?
Will do.
> Thanks,
> ferruh
next prev parent reply other threads:[~2019-07-30 17:30 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-09 11:09 [dpdk-dev] " Bernard Iremonger
2019-07-10 21:48 ` Thomas Monjalon
2019-07-29 13:09 ` David Marchand
2019-07-30 14:42 ` Aaron Conole
2019-07-30 14:48 ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2019-07-30 15:43 ` Aaron Conole
2019-07-30 16:55 ` Ferruh Yigit
2019-07-30 17:30 ` Aaron Conole [this message]
2019-07-30 16:18 ` Adrien Mazarguil
2019-07-30 16:35 ` Ferruh Yigit
2019-07-30 17:27 ` Aaron Conole
2019-07-30 18:51 ` Adrien Mazarguil
2019-07-30 14:44 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f7ta7cvl9as.fsf@dhcp-25.97.bos.redhat.com \
--to=aconole@redhat.com \
--cc=adrien.mazarguil@6wind.com \
--cc=bernard.iremonger@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=flavia.musatescu@intel.com \
--cc=jasvinder.singh@intel.com \
--cc=stable@dpdk.org \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).