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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Fábio Olivé 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=14546 .

Reported-by: argp@xxxxxxxxxxxxxxx
Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
Signed-off-by: Fábio Olivé Leite <fleite@xxxxxxxxxx>
---

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() and
+ * 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;
 
-	if (uaddr_len > sizeof(buf))
+	if (uaddr_len > RPCBIND_MAXUADDRLEN)
 		return 0;
 
 	memcpy(buf, uaddr, uaddr_len);
 
-	buf[uaddr_len] = '\n';
-	buf[uaddr_len + 1] = '\0';
-
+	buf[uaddr_len] = '\0';
 	c = strrchr(buf, '.');
 	if (unlikely(c == 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;
 
-	c[0] = '\n';
-	c[1] = '\0';
-
+	*c = '\0';
 	c = strrchr(buf, '.');
 	if (unlikely(c == NULL))
 		return 0;
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
 
 	port = (unsigned short)((porthi << 8) | portlo);
 
-	c[0] = '\0';
-
+	*c = '\0';
 	if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
 		return 0;
 

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux