2009-11-13 15:53:15

by Chuck Lever III

[permalink] [raw]
Subject: [PATCH] SUNRPC: Address buffer overrun in rpc_uaddr2sockaddr()

The size of buf[] must account for the string termination needed for
the first strict_strtoul() call. Introduced in commit a02d6926.

=46=C3=A1bio Oliv=C3=A9 Leite points out that strict_strtoul() requires=
_either_
'\n\0' _or_ '\0' termination, so use the simpler '\0' here instead.

See http://bugzilla.kernel.org/show_bug.cgi?id=3D14546 .

Reported-by: [email protected]
Signed-off-by: Chuck Lever <[email protected]>
Signed-off-by: F=C3=A1bio Oliv=C3=A9 Leite <[email protected]>
---

Hi Trond-

I haven't heard from the reporter, but since 2.6.32-final is imminent,
would you consider this for 2.6.32-rc ? As far as I can tell, this
issue was introduced in 2.6.32-rc and is not applicable for stable.

Thanks.

net/sunrpc/addr.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index 22e8fd8..c7450c8 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
* @sap: buffer into which to plant socket address
* @salen: size of buffer
*
+ * @uaddr does not have to be '\0'-terminated, but strict_strtoul() an=
d
+ * rpc_pton() require proper string termination to be successful.
+ *
* Returns the size of the socket address if successful; otherwise
* zero is returned.
*/
size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
struct sockaddr *sap, const size_t salen)
{
- char *c, buf[RPCBIND_MAXUADDRLEN];
+ char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')];
unsigned long portlo, porthi;
unsigned short port;
=20
- if (uaddr_len > sizeof(buf))
+ if (uaddr_len > RPCBIND_MAXUADDRLEN)
return 0;
=20
memcpy(buf, uaddr, uaddr_len);
=20
- buf[uaddr_len] =3D '\n';
- buf[uaddr_len + 1] =3D '\0';
-
+ buf[uaddr_len] =3D '\0';
c =3D strrchr(buf, '.');
if (unlikely(c =3D=3D NULL))
return 0;
@@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const =
size_t uaddr_len,
if (unlikely(portlo > 255))
return 0;
=20
- c[0] =3D '\n';
- c[1] =3D '\0';
-
+ *c =3D '\0';
c =3D strrchr(buf, '.');
if (unlikely(c =3D=3D NULL))
return 0;
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const =
size_t uaddr_len,
=20
port =3D (unsigned short)((porthi << 8) | portlo);
=20
- c[0] =3D '\0';
-
+ *c =3D '\0';
if (rpc_pton(buf, strlen(buf), sap, salen) =3D=3D 0)
return 0;
=20



2009-11-13 23:23:07

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH] SUNRPC: Address buffer overrun in rpc_uaddr2sockaddr()

On Fri, 2009-11-13 at 10:52 -0500, Chuck Lever wrote:
> Hi Trond-
>
> I haven't heard from the reporter, but since 2.6.32-final is imminent,
> would you consider this for 2.6.32-rc ? As far as I can tell, this
> issue was introduced in 2.6.32-rc and is not applicable for stable.

I've put it in the 'bugfixes' and 'linux-next' git trees. We'll give it
a few days testing there before I ask Linus to pull.

Cheers
Trond


2009-11-16 16:39:33

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH] SUNRPC: Address buffer overrun in rpc_uaddr2sockaddr()

On Nov 13, 2009, at 6:23 PM, Trond Myklebust wrote:
> On Fri, 2009-11-13 at 10:52 -0500, Chuck Lever wrote:
>> Hi Trond-
>>
>> I haven't heard from the reporter, but since 2.6.32-final is
>> imminent,
>> would you consider this for 2.6.32-rc ? As far as I can tell, this
>> issue was introduced in 2.6.32-rc and is not applicable for stable.
>
> I've put it in the 'bugfixes' and 'linux-next' git trees. We'll give
> it
> a few days testing there before I ask Linus to pull.

Excellent, thanks.

--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com