CVE-2012-1097 regset: Prevent null pointer reference on readonly regsets

This commit is contained in:
Josh Boyer 2012-03-05 09:40:00 -05:00
parent be72cc46b5
commit 3bb94782bd
3 changed files with 121 additions and 1 deletions

View File

@ -42,7 +42,7 @@ Summary: The Linux kernel
# When changing real_sublevel below, reset this by hand to 1
# (or to 0 and then use rpmdev-bumpspec).
#
%global baserelease 1
%global baserelease 2
%global fedora_build %{baserelease}
# real_sublevel is the 3.x kernel version we're starting with
@ -724,6 +724,10 @@ Patch21104: sony-laptop-Enable-keyboard-backlight-by-default.patch
# Disable threading in hibernate compression
Patch21105: disable-threading-in-compression-for-hibernate.patch
#rhbz 799782 CVE-2012-1097
Patch21106: regset-Prevent-null-pointer-reference-on-readonly-re.patch
Patch21107: regset-Return-EFAULT-not-EIO-on-host-side-memory-fau.patch
Patch21200: unhandled-irqs-switch-to-polling.patch
%endif
@ -1341,6 +1345,10 @@ ApplyPatch sony-laptop-Enable-keyboard-backlight-by-default.patch
#Disable threading in hibernate compression
ApplyPatch disable-threading-in-compression-for-hibernate.patch
#rhbz 799782 CVE-2012-1097
ApplyPatch regset-Prevent-null-pointer-reference-on-readonly-re.patch
ApplyPatch regset-Return-EFAULT-not-EIO-on-host-side-memory-fau.patch
ApplyPatch unhandled-irqs-switch-to-polling.patch
# END OF PATCH APPLICATIONS
@ -1990,6 +1998,9 @@ fi
# and build.
%changelog
* Mon Mar 05 2012 Josh Boyer <jwboyer@redhat.com>
- CVE-2012-1097 regset: Prevent null pointer reference on readonly regsets
* Fri Mar 02 2012 Dave Jones <davej@redhat.com>
- Enable VM debugging in non-debug kernels too.

View File

@ -0,0 +1,63 @@
From c8e252586f8d5de906385d8cf6385fee289a825e Mon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <hpa@zytor.com>
Date: Fri, 2 Mar 2012 10:43:48 -0800
Subject: [PATCH 1/2] regset: Prevent null pointer reference on readonly
regsets
The regset common infrastructure assumed that regsets would always
have .get and .set methods, but not necessarily .active methods.
Unfortunately people have since written regsets without .set methods.
Rather than putting in stub functions everywhere, handle regsets with
null .get or .set methods explicitly.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Roland McGrath <roland@hack.frob.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
fs/binfmt_elf.c | 2 +-
include/linux/regset.h | 6 ++++++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bcb884e..07d096c 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1421,7 +1421,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
for (i = 1; i < view->n; ++i) {
const struct user_regset *regset = &view->regsets[i];
do_thread_regset_writeback(t->task, regset);
- if (regset->core_note_type &&
+ if (regset->core_note_type && regset->get &&
(!regset->active || regset->active(t->task, regset))) {
int ret;
size_t size = regset->n * regset->size;
diff --git a/include/linux/regset.h b/include/linux/regset.h
index 8abee65..5150fd1 100644
--- a/include/linux/regset.h
+++ b/include/linux/regset.h
@@ -335,6 +335,9 @@ static inline int copy_regset_to_user(struct task_struct *target,
{
const struct user_regset *regset = &view->regsets[setno];
+ if (!regset->get)
+ return -EOPNOTSUPP;
+
if (!access_ok(VERIFY_WRITE, data, size))
return -EIO;
@@ -358,6 +361,9 @@ static inline int copy_regset_from_user(struct task_struct *target,
{
const struct user_regset *regset = &view->regsets[setno];
+ if (!regset->set)
+ return -EOPNOTSUPP;
+
if (!access_ok(VERIFY_READ, data, size))
return -EIO;
--
1.7.7.6

View File

@ -0,0 +1,46 @@
From 5189fa19a4b2b4c3bec37c3a019d446148827717 Mon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <hpa@zytor.com>
Date: Fri, 2 Mar 2012 10:43:49 -0800
Subject: [PATCH 2/2] regset: Return -EFAULT, not -EIO, on host-side memory
fault
There is only one error code to return for a bad user-space buffer
pointer passed to a system call in the same address space as the
system call is executed, and that is EFAULT. Furthermore, the
low-level access routines, which catch most of the faults, return
EFAULT already.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Roland McGrath <roland@hack.frob.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
include/linux/regset.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/regset.h b/include/linux/regset.h
index 5150fd1..686f373 100644
--- a/include/linux/regset.h
+++ b/include/linux/regset.h
@@ -339,7 +339,7 @@ static inline int copy_regset_to_user(struct task_struct *target,
return -EOPNOTSUPP;
if (!access_ok(VERIFY_WRITE, data, size))
- return -EIO;
+ return -EFAULT;
return regset->get(target, regset, offset, size, NULL, data);
}
@@ -365,7 +365,7 @@ static inline int copy_regset_from_user(struct task_struct *target,
return -EOPNOTSUPP;
if (!access_ok(VERIFY_READ, data, size))
- return -EIO;
+ return -EFAULT;
return regset->set(target, regset, offset, size, NULL, data);
}
--
1.7.7.6