Patchwork [3.5.yuz,extended,stable] Patch "libceph: fix overflow in __decode_pool_names()" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Nov. 20, 2012, 5:16 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/200426/
State New
Headers show


Herton Ronaldo Krzesinski - Nov. 20, 2012, 5:16 p.m.
This is a note to let you know that I have just added a patch titled

    libceph: fix overflow in __decode_pool_names()

to the linux-3.5.y-queue branch of the 3.5.yuz extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.yuz tree, see



From 4e4029e83fcb595985cbc32e88e0894e4f7fb066 Mon Sep 17 00:00:00 2001
From: Xi Wang <>
Date: Wed, 6 Jun 2012 19:35:55 -0500
Subject: [PATCH 19/78] libceph: fix overflow in __decode_pool_names()

commit ad3b904c07dfa88603689bf9a67bffbb9b99beb5 upstream.

`len' is read from network and thus needs validation.  Otherwise a
large `len' would cause out-of-bounds access via the memcpy() call.
In addition, len = 0xffffffff would overflow the kmalloc() size,
leading to out-of-bounds write.

This patch adds a check of `len' via ceph_decode_need().  Also use
kstrndup rather than kmalloc/memcpy.

[ added -ENOMEM return for null kstrndup() result]

Signed-off-by: Xi Wang <>
Reviewed-by: Alex Elder <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 net/ceph/osdmap.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)



diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 81e3b84..95b2762 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -488,15 +488,16 @@  static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
 		ceph_decode_32_safe(p, end, pool, bad);
 		ceph_decode_32_safe(p, end, len, bad);
 		dout("  pool %d len %d\n", pool, len);
+		ceph_decode_need(p, end, len, bad);
 		pi = __lookup_pg_pool(&map->pg_pools, pool);
 		if (pi) {
+			char *name = kstrndup(*p, len, GFP_NOFS);
+			if (!name)
+				return -ENOMEM;
-			pi->name = kmalloc(len + 1, GFP_NOFS);
-			if (pi->name) {
-				memcpy(pi->name, *p, len);
-				pi->name[len] = '\0';
-				dout("  name is %s\n", pi->name);
-			}
+			pi->name = name;
+			dout("  name is %s\n", pi->name);
 		*p += len;