Ferruh Yigit <ferruh.yi...@intel.com> writes: > On 7/30/2019 4:43 PM, Aaron Conole wrote: >> Ferruh Yigit <ferruh.yi...@intel.com> writes: >> >>> On 7/30/2019 3:42 PM, Aaron Conole wrote: >>>> David Marchand <david.march...@redhat.com> writes: >>>> >>>>> On Wed, Jul 10, 2019 at 11:49 PM Thomas Monjalon <tho...@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: sta...@dpdk.org >>>>>>> Signed-off-by: Bernard Iremonger <bernard.iremon...@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 <acon...@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