2014-06-07 17:57:03

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH] dns_resolver: assure that dns_query() result is null-terminated

dns_query() credulously assumes that keys are null-terminated and
returns a copy of a memory block that is off by one.
---
net/dns_resolver/dns_query.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
index e7b6d53..53be635 100644
--- a/net/dns_resolver/dns_query.c
+++ b/net/dns_resolver/dns_query.c
@@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen,
if (!*_result)
goto put;

- memcpy(*_result, upayload->data, len + 1);
+ memcpy(*_result, upayload->data, len);
+ *_result[len+1] = '\0';
+
if (_expiry)
*_expiry = rkey->expiry;

--
1.7.10.4


2014-06-07 18:55:00

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH] dns_resolver: assure that dns_query() result is null-terminated

On Sat, Jun 7, 2014 at 1:56 PM, Manuel Schölling
<[email protected]> wrote:
> dns_query() credulously assumes that keys are null-terminated and
> returns a copy of a memory block that is off by one.
> ---
> net/dns_resolver/dns_query.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
> index e7b6d53..53be635 100644
> --- a/net/dns_resolver/dns_query.c
> +++ b/net/dns_resolver/dns_query.c
> @@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen,
> if (!*_result)
> goto put;
>
> - memcpy(*_result, upayload->data, len + 1);
> + memcpy(*_result, upayload->data, len);
> + *_result[len+1] = '\0';

Off by one...

> +
> if (_expiry)
> *_expiry = rkey->expiry;
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/



--
Trond Myklebust

Linux NFS client maintainer, PrimaryData

[email protected]

2014-06-07 18:57:45

by Manuel Schölling

[permalink] [raw]
Subject: Re: [PATCH] dns_resolver: assure that dns_query() result is null-terminated

LOL, that was stupid!
Sorry, I'll send a corrected version in a second...

On Sa, 2014-06-07 at 14:54 -0400, Trond Myklebust wrote:
> On Sat, Jun 7, 2014 at 1:56 PM, Manuel Schölling
> <[email protected]> wrote:
> > dns_query() credulously assumes that keys are null-terminated and
> > returns a copy of a memory block that is off by one.
> > ---
> > net/dns_resolver/dns_query.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
> > index e7b6d53..53be635 100644
> > --- a/net/dns_resolver/dns_query.c
> > +++ b/net/dns_resolver/dns_query.c
> > @@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen,
> > if (!*_result)
> > goto put;
> >
> > - memcpy(*_result, upayload->data, len + 1);
> > + memcpy(*_result, upayload->data, len);
> > + *_result[len+1] = '\0';
>
> Off by one...
>
> > +
> > if (_expiry)
> > *_expiry = rkey->expiry;
> >
> > --
> > 1.7.10.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
>
>
>

2014-06-07 19:01:31

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH v2] dns_resolver: assure that dns_query() result is null-terminated

dns_query() credulously assumes that keys are null-terminated and
returns a copy of a memory block that is off by one.
---
net/dns_resolver/dns_query.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
index e7b6d53..84871a2 100644
--- a/net/dns_resolver/dns_query.c
+++ b/net/dns_resolver/dns_query.c
@@ -145,11 +145,11 @@ int dns_query(const char *type, const char *name, size_t namelen,
len = upayload->datalen;

ret = -ENOMEM;
- *_result = kmalloc(len + 1, GFP_KERNEL);
+ *_result = kzalloc(len + 1, GFP_KERNEL);
if (!*_result)
goto put;

- memcpy(*_result, upayload->data, len + 1);
+ memcpy(*_result, upayload->data, len);
if (_expiry)
*_expiry = rkey->expiry;

--
1.7.10.4

2014-06-07 21:43:05

by David Rientjes

[permalink] [raw]
Subject: Re: [PATCH v2] dns_resolver: assure that dns_query() result is null-terminated

On Sat, 7 Jun 2014, Manuel Schölling wrote:

> dns_query() credulously assumes that keys are null-terminated and
> returns a copy of a memory block that is off by one.

No sign-off? Please read Documentation/SubmittingPatches.

> ---
> net/dns_resolver/dns_query.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
> index e7b6d53..84871a2 100644
> --- a/net/dns_resolver/dns_query.c
> +++ b/net/dns_resolver/dns_query.c
> @@ -145,11 +145,11 @@ int dns_query(const char *type, const char *name, size_t namelen,
> len = upayload->datalen;
>
> ret = -ENOMEM;
> - *_result = kmalloc(len + 1, GFP_KERNEL);
> + *_result = kzalloc(len + 1, GFP_KERNEL);
> if (!*_result)
> goto put;
>
> - memcpy(*_result, upayload->data, len + 1);
> + memcpy(*_result, upayload->data, len);
> if (_expiry)
> *_expiry = rkey->expiry;
>

kzalloc() would be unnecessary overhead (zeroing definitely comes with a
cost) if you're going to copy to the memory immediately afterwards. Just
leave the kmalloc(), do the memcpy() and explicitly zero terminate it
_result.

2014-06-07 21:53:38

by Manuel Schölling

[permalink] [raw]
Subject: Re: [PATCH v2] dns_resolver: assure that dns_query() result is null-terminated

On Sa, 2014-06-07 at 14:42 -0700, David Rientjes wrote:
> On Sat, 7 Jun 2014, Manuel Schölling wrote:
>
> > dns_query() credulously assumes that keys are null-terminated and
> > returns a copy of a memory block that is off by one.
>
> No sign-off? Please read Documentation/SubmittingPatches.
It's just not my day today.
Sorry, I forgot about the sign-off.

> > ---
> > net/dns_resolver/dns_query.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
> > index e7b6d53..84871a2 100644
> > --- a/net/dns_resolver/dns_query.c
> > +++ b/net/dns_resolver/dns_query.c
> > @@ -145,11 +145,11 @@ int dns_query(const char *type, const char *name, size_t namelen,
> > len = upayload->datalen;
> >
> > ret = -ENOMEM;
> > - *_result = kmalloc(len + 1, GFP_KERNEL);
> > + *_result = kzalloc(len + 1, GFP_KERNEL);
> > if (!*_result)
> > goto put;
> >
> > - memcpy(*_result, upayload->data, len + 1);
> > + memcpy(*_result, upayload->data, len);
> > if (_expiry)
> > *_expiry = rkey->expiry;
> >
>
> kzalloc() would be unnecessary overhead (zeroing definitely comes with a
> cost) if you're going to copy to the memory immediately afterwards. Just
> leave the kmalloc(), do the memcpy() and explicitly zero terminate it
> _result.

Using kzalloc() was suggested of a developer on IRC (#kernelnewbies) but
if you prefer kmalloc, that's ok, too.
I'll send you a corrected patch in a second.

2014-06-07 21:58:23

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH v2] dns_resolver: assure that dns_query() result is null-terminated

On 06/08/2014 01:42 AM, David Rientjes wrote:

>> dns_query() credulously assumes that keys are null-terminated and
>> returns a copy of a memory block that is off by one.

> No sign-off? Please read Documentation/SubmittingPatches.

>> ---
>> net/dns_resolver/dns_query.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
>> index e7b6d53..84871a2 100644
>> --- a/net/dns_resolver/dns_query.c
>> +++ b/net/dns_resolver/dns_query.c
>> @@ -145,11 +145,11 @@ int dns_query(const char *type, const char *name, size_t namelen,
>> len = upayload->datalen;
>>
>> ret = -ENOMEM;
>> - *_result = kmalloc(len + 1, GFP_KERNEL);
>> + *_result = kzalloc(len + 1, GFP_KERNEL);
>> if (!*_result)
>> goto put;
>>
>> - memcpy(*_result, upayload->data, len + 1);
>> + memcpy(*_result, upayload->data, len);
>> if (_expiry)
>> *_expiry = rkey->expiry;

> kzalloc() would be unnecessary overhead (zeroing definitely comes with a
> cost) if you're going to copy to the memory immediately afterwards. Just
> leave the kmalloc(), do the memcpy() and explicitly zero terminate it
> _result.

You can also replace kmalloc()/memcpy() with kmemdup().

WBR, Sergei

2014-06-07 21:58:12

by Manuel Schölling

[permalink] [raw]
Subject: [PATCH v3] dns_resolver: assure that dns_query() result is null-terminated

dns_query() credulously assumes that keys are null-terminated and
returns a copy of a memory block that is off by one.

Signed-off-by: Manuel Schölling <[email protected]>
---
net/dns_resolver/dns_query.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
index e7b6d53..6853d22 100644
--- a/net/dns_resolver/dns_query.c
+++ b/net/dns_resolver/dns_query.c
@@ -149,7 +149,9 @@ int dns_query(const char *type, const char *name, size_t namelen,
if (!*_result)
goto put;

- memcpy(*_result, upayload->data, len + 1);
+ memcpy(*_result, upayload->data, len);
+ *_result[len] = '\0';
+
if (_expiry)
*_expiry = rkey->expiry;

--
1.7.10.4

2014-06-07 22:02:42

by David Rientjes

[permalink] [raw]
Subject: Re: [PATCH v2] dns_resolver: assure that dns_query() result is null-terminated

On Sat, 7 Jun 2014, Manuel Schoelling wrote:

> > kzalloc() would be unnecessary overhead (zeroing definitely comes with a
> > cost) if you're going to copy to the memory immediately afterwards. Just
> > leave the kmalloc(), do the memcpy() and explicitly zero terminate it
> > _result.
>
> Using kzalloc() was suggested of a developer on IRC (#kernelnewbies) but
> if you prefer kmalloc, that's ok, too.
> I'll send you a corrected patch in a second.
>

Using kzalloc() here instead of kmalloc() is functionally equivalent to

if (*_result) {
memset(*_result, 0, len + 1);
memcpy(*_result, upayload->data, len);
}

so for anything with len > 1 there is an unnecessary overhead in doing
this. k?alloc() can return object sizes larger than len + 1 here as well
(usually power-of-2 sizes are supported by the slab allocator) so
depending on the value of len, you may be zeroing more memory than
copying.

Your first patch had the right idea, it's just off by one.

2014-06-11 07:12:19

by David Miller

[permalink] [raw]
Subject: Re: [PATCH v3] dns_resolver: assure that dns_query() result is null-terminated

From: Manuel Sch?lling <[email protected]>
Date: Sat, 7 Jun 2014 23:57:25 +0200

> dns_query() credulously assumes that keys are null-terminated and
> returns a copy of a memory block that is off by one.
>
> Signed-off-by: Manuel Sch?lling <[email protected]>

Applied, thanks.