Skip to content

Commit 2702b15

Browse files
keestorvalds
authored andcommitted
kernel/sys.c: fix stack memory content leak via UNAME26
Calling uname() with the UNAME26 personality set allows a leak of kernel stack contents. This fixes it by defensively calculating the length of copy_to_user() call, making the len argument unsigned, and initializing the stack buffer to zero (now technically unneeded, but hey, overkill). CVE-2012-0957 Reported-by: PaX Team <pageexec@freemail.hu> Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Andi Kleen <ak@linux.intel.com> Cc: PaX Team <pageexec@freemail.hu> Cc: Brad Spengler <spender@grsecurity.net> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 1d46e23 commit 2702b15

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

Diff for: kernel/sys.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -1265,15 +1265,16 @@ DECLARE_RWSEM(uts_sem);
12651265
* Work around broken programs that cannot handle "Linux 3.0".
12661266
* Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
12671267
*/
1268-
static int override_release(char __user *release, int len)
1268+
static int override_release(char __user *release, size_t len)
12691269
{
12701270
int ret = 0;
1271-
char buf[65];
12721271

12731272
if (current->personality & UNAME26) {
1274-
char *rest = UTS_RELEASE;
1273+
const char *rest = UTS_RELEASE;
1274+
char buf[65] = { 0 };
12751275
int ndots = 0;
12761276
unsigned v;
1277+
size_t copy;
12771278

12781279
while (*rest) {
12791280
if (*rest == '.' && ++ndots >= 3)
@@ -1283,8 +1284,9 @@ static int override_release(char __user *release, int len)
12831284
rest++;
12841285
}
12851286
v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
1286-
snprintf(buf, len, "2.6.%u%s", v, rest);
1287-
ret = copy_to_user(release, buf, len);
1287+
copy = min(sizeof(buf), max_t(size_t, 1, len));
1288+
copy = scnprintf(buf, copy, "2.6.%u%s", v, rest);
1289+
ret = copy_to_user(release, buf, copy + 1);
12881290
}
12891291
return ret;
12901292
}

0 commit comments

Comments
 (0)