[v2] net/ring: fix unchecked return value
Checks
Commit Message
Add a check for the return value of the sscanf call in
parse_internal_args(), returning an error if we don't get the expected
result.
Coverity issue: 362049
Fixes: 96cb19521147 ("net/ring: use EAL APIs in PMD specific API")
Cc: stable@dpdk.org
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
---
v2: added consumed characters count check
---
drivers/net/ring/rte_eth_ring.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Comments
On 10/1/2020 6:09 PM, Kevin Laatz wrote:
> Add a check for the return value of the sscanf call in
> parse_internal_args(), returning an error if we don't get the expected
> result.
>
> Coverity issue: 362049
> Fixes: 96cb19521147 ("net/ring: use EAL APIs in PMD specific API")
> Cc: stable@dpdk.org
>
> Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
>
> ---
> v2: added consumed characters count check
> ---
> drivers/net/ring/rte_eth_ring.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> index 40fe1ca4ba..66367465fd 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -538,8 +538,13 @@ parse_internal_args(const char *key __rte_unused, const char *value,
> {
> struct ring_internal_args **internal_args = data;
> void *args;
> + int n;
>
> - sscanf(value, "%p", &args);
> + if (sscanf(value, "%p%n", &args, &n) != 1 || (size_t)n != strlen(value)) {
two small details,
1- I see following note in the sscanf manual: https://linux.die.net/man/3/sscanf
"
The C standard says: "Execution of a %n directive does not increment the
assignment count returned at the completion of execution" but the Corrigendum
seems to contradict this. Probably it is wise not to make any assumptions on the
effect of %n conversions on the return value.
"
So what do you think checking return value as " == 0" ?
2) If the 'value' is more than a pointer can hold, like "0xbbbbbbbbbbbbbbbbbb",
the arg will be '0xffffffffffffffff', the 'n' will be 20.
The "(size_t)n != strlen(value)" check doesn't catch this.
What do you think adding another "strnlen(value, 18)", since 18 can be the
largest pointer, even before 'sscanf()' ? This also protects against strlen with
non-null terminated 'value'.
> + PMD_LOG(ERR, "Error parsing internal args");
> +
> + return -1;
> + }
>
> *internal_args = args;
>
>
On Mon, Oct 12, 2020 at 12:57:11PM +0100, Ferruh Yigit wrote:
> On 10/1/2020 6:09 PM, Kevin Laatz wrote:
> > Add a check for the return value of the sscanf call in
> > parse_internal_args(), returning an error if we don't get the expected
> > result.
> >
> > Coverity issue: 362049
> > Fixes: 96cb19521147 ("net/ring: use EAL APIs in PMD specific API")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
> >
> > ---
> > v2: added consumed characters count check
> > ---
> > drivers/net/ring/rte_eth_ring.c | 7 ++++++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> > index 40fe1ca4ba..66367465fd 100644
> > --- a/drivers/net/ring/rte_eth_ring.c
> > +++ b/drivers/net/ring/rte_eth_ring.c
> > @@ -538,8 +538,13 @@ parse_internal_args(const char *key __rte_unused, const char *value,
> > {
> > struct ring_internal_args **internal_args = data;
> > void *args;
> > + int n;
> > - sscanf(value, "%p", &args);
> > + if (sscanf(value, "%p%n", &args, &n) != 1 || (size_t)n != strlen(value)) {
>
> two small details,
>
> 1- I see following note in the sscanf manual: https://linux.die.net/man/3/sscanf
> "
> The C standard says: "Execution of a %n directive does not increment the
> assignment count returned at the completion of execution" but the
> Corrigendum seems to contradict this. Probably it is wise not to make any
> assumptions on the effect of %n conversions on the return value.
> "
>
> So what do you think checking return value as " == 0" ?
>
Maybe in that copy of the man page but on my Ubuntu system there is no such
disclaimer, and I don't see it either on the kernel.org man page reference:
https://man7.org/linux/man-pages/man3/sscanf.3.html
That official man page reference clearly states that the behaviour is that
%n does not increase the reference count.
On 10/12/2020 1:45 PM, Bruce Richardson wrote:
> On Mon, Oct 12, 2020 at 12:57:11PM +0100, Ferruh Yigit wrote:
>> On 10/1/2020 6:09 PM, Kevin Laatz wrote:
>>> Add a check for the return value of the sscanf call in
>>> parse_internal_args(), returning an error if we don't get the expected
>>> result.
>>>
>>> Coverity issue: 362049
>>> Fixes: 96cb19521147 ("net/ring: use EAL APIs in PMD specific API")
>>> Cc: stable@dpdk.org
>>>
>>> Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
>>>
>>> ---
>>> v2: added consumed characters count check
>>> ---
>>> drivers/net/ring/rte_eth_ring.c | 7 ++++++-
>>> 1 file changed, 6 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
>>> index 40fe1ca4ba..66367465fd 100644
>>> --- a/drivers/net/ring/rte_eth_ring.c
>>> +++ b/drivers/net/ring/rte_eth_ring.c
>>> @@ -538,8 +538,13 @@ parse_internal_args(const char *key __rte_unused, const char *value,
>>> {
>>> struct ring_internal_args **internal_args = data;
>>> void *args;
>>> + int n;
>>> - sscanf(value, "%p", &args);
>>> + if (sscanf(value, "%p%n", &args, &n) != 1 || (size_t)n != strlen(value)) {
>>
>> two small details,
>>
>> 1- I see following note in the sscanf manual: https://linux.die.net/man/3/sscanf
>> "
>> The C standard says: "Execution of a %n directive does not increment the
>> assignment count returned at the completion of execution" but the
>> Corrigendum seems to contradict this. Probably it is wise not to make any
>> assumptions on the effect of %n conversions on the return value.
>> "
>>
>> So what do you think checking return value as " == 0" ?
>>
>
> Maybe in that copy of the man page but on my Ubuntu system there is no such
> disclaimer, and I don't see it either on the kernel.org man page reference:
>
> https://man7.org/linux/man-pages/man3/sscanf.3.html
>
> That official man page reference clearly states that the behaviour is that
> %n does not increase the reference count.
>
My Linux box also doesn't have that note, but just to prevent the PMD fails for
something like this.
Do you see any downside of checking as "sscanf() == 0"?
On Mon, Oct 12, 2020 at 02:04:26PM +0100, Ferruh Yigit wrote:
> On 10/12/2020 1:45 PM, Bruce Richardson wrote:
> > On Mon, Oct 12, 2020 at 12:57:11PM +0100, Ferruh Yigit wrote:
> > > On 10/1/2020 6:09 PM, Kevin Laatz wrote:
> > > > Add a check for the return value of the sscanf call in
> > > > parse_internal_args(), returning an error if we don't get the expected
> > > > result.
> > > >
> > > > Coverity issue: 362049
> > > > Fixes: 96cb19521147 ("net/ring: use EAL APIs in PMD specific API")
> > > > Cc: stable@dpdk.org
> > > >
> > > > Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
> > > >
> > > > ---
> > > > v2: added consumed characters count check
> > > > ---
> > > > drivers/net/ring/rte_eth_ring.c | 7 ++++++-
> > > > 1 file changed, 6 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> > > > index 40fe1ca4ba..66367465fd 100644
> > > > --- a/drivers/net/ring/rte_eth_ring.c
> > > > +++ b/drivers/net/ring/rte_eth_ring.c
> > > > @@ -538,8 +538,13 @@ parse_internal_args(const char *key __rte_unused, const char *value,
> > > > {
> > > > struct ring_internal_args **internal_args = data;
> > > > void *args;
> > > > + int n;
> > > > - sscanf(value, "%p", &args);
> > > > + if (sscanf(value, "%p%n", &args, &n) != 1 || (size_t)n != strlen(value)) {
> > >
> > > two small details,
> > >
> > > 1- I see following note in the sscanf manual: https://linux.die.net/man/3/sscanf
> > > "
> > > The C standard says: "Execution of a %n directive does not increment the
> > > assignment count returned at the completion of execution" but the
> > > Corrigendum seems to contradict this. Probably it is wise not to make any
> > > assumptions on the effect of %n conversions on the return value.
> > > "
> > >
> > > So what do you think checking return value as " == 0" ?
> > >
> >
> > Maybe in that copy of the man page but on my Ubuntu system there is no such
> > disclaimer, and I don't see it either on the kernel.org man page reference:
> >
> > https://man7.org/linux/man-pages/man3/sscanf.3.html
> >
> > That official man page reference clearly states that the behaviour is that
> > %n does not increase the reference count.
> >
>
> My Linux box also doesn't have that note, but just to prevent the PMD fails
> for something like this.
>
> Do you see any downside of checking as "sscanf() == 0"?
>
Nope, no issue with checking that too.
/Bruce
@@ -538,8 +538,13 @@ parse_internal_args(const char *key __rte_unused, const char *value,
{
struct ring_internal_args **internal_args = data;
void *args;
+ int n;
- sscanf(value, "%p", &args);
+ if (sscanf(value, "%p%n", &args, &n) != 1 || (size_t)n != strlen(value)) {
+ PMD_LOG(ERR, "Error parsing internal args");
+
+ return -1;
+ }
*internal_args = args;