oprofile fixes for 3.2
Subsystems (4)
Ingo,
please pull this one fix for 3.2.
Thanks,
-Robert
The following changes since commit dc47ce90c3a822cd7c9e9339fe4d5f61dcb26b50:
Linux 3.2-rc5 (2011-12-09 15:09:32 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile.git urgent
Robert Richter (1):
oprofile: Fix uninitialized memory access when writing to oprofilefs
arch/s390/oprofile/init.c | 3 +++ drivers/oprofile/oprofile_files.c | 9 +++++++++ drivers/oprofile/oprofilefs.c | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 1 deletions(-)
PATCH 1/1 oprofile: Fix uninitialized memory access when writing to oprofilefs
If oprofilefs_ulong_from_user() is called with count equals zero, *val must be initialized. Otherwise *val is later used uninitialized as no error is returned. Alternatively oprofilefs_ulong_from_user() may not be called if !count. This patch fixes usage of oprofilefs_ulong_from_ user().
This follows write syscall implementation when count is zero: "If count is zero ... [and if] no errors are detected, 0 will be returned without causing any other effect." (man 2 write)
--- arch/s390/oprofile/init.c | 3 +++ drivers/oprofile/oprofile_files.c | 9 +++++++++ drivers/oprofile/oprofilefs.c | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 1 deletions(-)
arch/s390/oprofile/init.c +3 -0
@@ -87,6 +87,9 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf,if (*offset)return -EINVAL ; +if (!count) +return 0 ; + retval =oprofilefs_ulong_from_user (&val, buf, count);if (retval)return retval;
drivers/oprofile/oprofile_files.c +9 -0
@@ -44,6 +44,9 @@ static ssize_t timeout_write(struct file *file, char const __user *buf,if (*offset)return -EINVAL ; +if (!count) +return 0 ; + retval =oprofilefs_ulong_from_user (&val, buf, count);if (retval)return retval;
@@ -83,6 +86,9 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t couif (!oprofile_ops.backtrace)return -EINVAL ; +if (!count) +return 0 ; + retval =oprofilefs_ulong_from_user (&val, buf, count);if (retval)return retval;
@@ -140,6 +146,9 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t coif (*offset)return -EINVAL ; +if (!count) +return 0 ; + retval =oprofilefs_ulong_from_user (&val, buf, count);if (retval)return retval;
drivers/oprofile/oprofilefs.c +14 -1
@@ -59,7 +59,17 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t coureturn simple_read_from_buffer (buf, count, offset, tmpbuf, maxlen); } - +/* +* Note: oprofilefs_ulong_from_user() must be called with *val +* initialized, otherwise *val is used uninitialized if !count. This +* follows write syscall implementation when count is zero: "If count +* is zero ... [and if] no errors are detected, 0 will be returned +* without causing any other effect." (man 2 write) +* +* In case *val is a temporary variable, oprofilefs_ulong_from_user() +* may not be called if !count. This causes race conditions due to +* missing locking of *var. +*/ int oprofilefs_ulong_from_user (unsigned long *val,char const __user *buf,size_t count) {char tmpbuf[TMPBUFSIZE ];
@@ -98,6 +108,9 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_if (*offset)return -EINVAL ; +if (!count) +return 0 ; + retval =oprofilefs_ulong_from_user (&value, buf, count);if (retval)return retval;
Signature · 1 line
1.7.7
Quoted 17 lines · Robert Richter
Ingo,
please pull this one fix for 3.2.
Thanks,
-Robert
The following changes since commit
dc47ce90c3a822cd7c9e9339fe4d5f61dcb26b50:Linux 3.2-rc5 (2011-12-09 15:09:32 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile.giturgent
Quoted 7 lines
Robert Richter (1):
oprofile: Fix uninitialized memory access when writing to oprofilefsarch/s390/oprofile/init.c | 3 +++ drivers/oprofile/oprofile_files.c | 9 +++++++++ drivers/oprofile/oprofilefs.c | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 1 deletions(-)
Hm, i really don't like this:
+ if (!count)
+ return 0;
+
retval = oprofilefs_ulong_from_user(&val, buf, count); if (retval)
return retval;
+ if (!count)
+ return 0;
+
retval = oprofilefs_ulong_from_user(&val, buf, count); if (retval)
return retval;
+ if (!count)
+ return 0;
+
retval = oprofilefs_ulong_from_user(&val, buf, count); if (retval)
return retval;
+ if (!count)
+ return 0;
+
retval = oprofilefs_ulong_from_user(&val, buf, count); if (retval)
return retval;
+ if (!count)
+ return 0;
+
retval = oprofilefs_ulong_from_user(&value, buf, count); if (retval)
return retval;
See the ugly and fragile pattern?
This should *really* be solved via the oprofilefs_ulong_from_user() helper function, not by sprinkling the !count checks in half a dozen places ...
Thanks,
Ingo
Quoted 7 lines · Ingo Molnar
(quoted diff) +3
-0+ if (!count) + return 0; + retval = oprofilefs_ulong_from_user(&value, buf, count); if (retval) return retval;
Quoted 5 lines
See the ugly and fragile pattern?
This should *really* be solved via the
oprofilefs_ulong_from_user()helper function, not by sprinkling the !count checks in half a dozen places ...
Hmm, I thought there was no way to leave the code path with count == 0 and retval. But thinking about it it would be possible with returning count or errors < 0. Will improve the patch.
Thanks,
-Robert
Signature · 2 lines
Advanced Micro Devices, Inc. Operating System Research Center
PATCH v2 1/1 oprofile: Fix uninitialized memory access when writing to
Quoted 11 lines · Robert Richter
Quoted 9 lines · Ingo Molnar
(quoted diff) +3
-0+ if (!count) + return 0; + retval = oprofilefs_ulong_from_user(&value, buf, count); if (retval) return retval;See the ugly and fragile pattern?
Quoted 7 lines
Quoted 3 lines
This should *really* be solved via the
oprofilefs_ulong_from_user()helper function, not by sprinkling the !count checks in half a dozen places ...Hmm, I thought there was no way to leave the code path with count == 0 and retval. But thinking about it it would be possible with returning count or errors < 0. Will improve the patch.
Ingo, see my updated version below. I am fine with appling it directly on tip/perf/urgent.
Thanks,
-Robert
--
Quoted 1 line
From
f07214bc05560f63da8404d31aa83034a16c6229Mon Sep 17 00:00:00 2001
From: Robert Richter <[email protected]>
Date: Fri, 16 Dec 2011 15:45:31 +0100
Subject: [PATCH] oprofile: Fix uninitialized memory access when writing to
oprofilefs
If oprofilefs_ulong_from_user() is called with count equals zero, *val remains unchanged. Depending on the implementation it might be uninitialized.
Change oprofilefs_ulong_from_user()'s interface to return count on success. Thus, we are able to return early if count equals zero which avoids using *val uninitialized. Fixing all users of oprofilefs_ulong_ from_user().
This follows write syscall implementation when count is zero: "If count is zero ... [and if] no errors are detected, 0 will be returned without causing any other effect." (man 2 write)
--- arch/s390/oprofile/init.c | 2 +- drivers/oprofile/oprofile_files.c | 7 ++++--- drivers/oprofile/oprofilefs.c | 11 +++++++++-- 3 files changed, 14 insertions(+), 6 deletions(-)
arch/s390/oprofile/init.c +1 -1
@@ -88,7 +88,7 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf,return -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval;if (oprofile_started)
drivers/oprofile/oprofile_files.c +4 -3
@@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf,return -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_timeout (val);
@@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t coureturn -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_ulong (&oprofile_backtrace_depth, val);
@@ -141,9 +141,10 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t coreturn -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; + retval =0 ;if (val) retval =oprofile_start ();else
drivers/oprofile/oprofilefs.c +9 -2
@@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou } +/* +* Note: If oprofilefs_ulong_from_user() returns 0, then *val remains +* unchanged and might be uninitialized. This follows write syscall +* implementation when count is zero: "If count is zero ... [and if] +* no errors are detected, 0 will be returned without causing any +* other effect." (man 2 write) +*/ int oprofilefs_ulong_from_user (unsigned long *val,char const __user *buf,size_t count) {char tmpbuf[TMPBUFSIZE ];
@@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_raw_spin_lock_irqsave (&oprofilefs_lock, flags); *val =simple_strtoul (tmpbuf,NULL ,0 );raw_spin_unlock_irqrestore (&oprofilefs_lock, flags); -return 0 ; +return count; }
@@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_return -EINVAL ; retval =oprofilefs_ulong_from_user (&value, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_ulong (file->private_data, value);
Signature · 8 lines
1.7.7 -- Advanced Micro Devices, Inc. Operating System Research Center
Ingo Molnar
AppliedRe: [PATCH v2] oprofile: Fix uninitialized memory access when writing to
Quoted 20 lines · Robert Richter
Quoted 11 lines · Robert Richter
Quoted 9 lines · Ingo Molnar
(quoted diff) +3
-0+ if (!count) + return 0; + retval = oprofilefs_ulong_from_user(&value, buf, count); if (retval) return retval;See the ugly and fragile pattern?
Quoted 7 lines
Quoted 3 lines
This should *really* be solved via the
oprofilefs_ulong_from_user()helper function, not by sprinkling the !count checks in half a dozen places ...Hmm, I thought there was no way to leave the code path with count == 0 and retval. But thinking about it it would be possible with returning count or errors < 0. Will improve the patch.
Quoted 1 line
Ingo, see my updated version below. [...]
Yeah, this looks a lot cleaner.
Quoted 1 line
[...] I am fine with appling it directly on tip/perf/urgent.
Applied,
Thanks,
Ingo
[tip:perf/urgent] oprofile: Fix uninitialized memory access when writing to writing to oprofilefs
In reply to Robert RichterCommit-ID: 913050b91eb94f194392dd797b1ff3779f606ac0 Gitweb: http://git.kernel.org/tip/913050b91eb94f194392dd797b1ff3779f606ac0 Author: Robert Richter <[email protected]> AuthorDate: Mon, 19 Dec 2011 16:38:30 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Mon, 19 Dec 2011 17:18:43 +0100
oprofile: Fix uninitialized memory access when writing to writing to oprofilefs
If oprofilefs_ulong_from_user() is called with count equals zero, *val remains unchanged. Depending on the implementation it might be uninitialized.
Change oprofilefs_ulong_from_user()'s interface to return count on success. Thus, we are able to return early if count equals zero which avoids using *val uninitialized. Fixing all users of oprofilefs_ulong_ from_user().
This follows write syscall implementation when count is zero:
"If count is zero ... [and if] no errors are detected, 0 will be returned without causing any other effect." (man 2 write)
--- arch/s390/oprofile/init.c | 2 +- drivers/oprofile/oprofile_files.c | 7 ++++--- drivers/oprofile/oprofilefs.c | 11 +++++++++-- 3 files changed, 14 insertions(+), 6 deletions(-)
arch/s390/oprofile/init.c +1 -1
@@ -88,7 +88,7 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf,return -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval;if (oprofile_started)
drivers/oprofile/oprofile_files.c +4 -3
@@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf,return -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_timeout (val);
@@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t coureturn -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_ulong (&oprofile_backtrace_depth, val);
@@ -141,9 +141,10 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t coreturn -EINVAL ; retval =oprofilefs_ulong_from_user (&val, buf, count); -if (retval) +if (retval <=0 )return retval; + retval =0 ;if (val) retval =oprofile_start ();else
drivers/oprofile/oprofilefs.c +9 -2
@@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou } +/* +* Note: If oprofilefs_ulong_from_user() returns 0, then *val remains +* unchanged and might be uninitialized. This follows write syscall +* implementation when count is zero: "If count is zero ... [and if] +* no errors are detected, 0 will be returned without causing any +* other effect." (man 2 write) +*/ int oprofilefs_ulong_from_user (unsigned long *val,char const __user *buf,size_t count) {char tmpbuf[TMPBUFSIZE ];
@@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_raw_spin_lock_irqsave (&oprofilefs_lock, flags); *val =simple_strtoul (tmpbuf,NULL ,0 );raw_spin_unlock_irqrestore (&oprofilefs_lock, flags); -return 0 ; +return count; }
@@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_return -EINVAL ; retval =oprofilefs_ulong_from_user (&value, buf, count); -if (retval) +if (retval <=0 )return retval; retval =oprofile_set_ulong (file->private_data, value);
PATCH 1/1 oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue
In reply to Robert RichterQuoted 1 line · Robert Richter
please pull this one fix for 3.2.
Ingo, yet another fix. Please apply to tip/perf/urgent.
Thanks,
-Robert
Quoted 1 line
From
a5ea1e51bb66c6081d081cd88d787f248e07d6afMon Sep 17 00:00:00 2001
From: Vladimir Zapolskiy <[email protected]>
Date: Thu, 22 Dec 2011 15:36:56 +0200
Subject: [PATCH] oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue
This change fixes a linking problem, which happens if oprofile is selected to be compiled as built-in:
oprofile_arch_exit' referenced in section .init.text' of arch/arm/oprofile/built-in.o: defined in discarded section `.exit.text' of arch/arm/oprofile/built-in.o
The problem is appeared after commit 87121ca504, which introduced oprofile_arch_exit() calls from __init function. Note that the aforementioned commit has been backported to stable branches, and the problem is known to be reproduced at least with 3.0.13 and 3.1.5 kernels.
--- arch/arm/oprofile/common.c | 2 +- arch/sh/oprofile/common.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/oprofile/common.c +1 -1
@@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)return oprofile_perf_init (ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit (void ) {oprofile_perf_exit (); }
arch/sh/oprofile/common.c +2 -2
@@ -49,7 +49,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)return oprofile_perf_init (ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit (void ) {oprofile_perf_exit ();kfree (sh_pmu_op_name);
@@ -60,5 +60,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->backtrace = sh_backtrace; return -ENODEV; } -void __exit oprofile_arch_exit(void) {} +void oprofile_arch_exit (void ) {}#endif /* CONFIG_HW_PERF_EVENTS */
Signature · 7 lines
1.7.8 -- Advanced Micro Devices, Inc. Operating System Research Center
[tip:perf/urgent] oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue
Commit-ID: 55205c916e179e09773d98d290334d319f45ac6b Gitweb: http://git.kernel.org/tip/55205c916e179e09773d98d290334d319f45ac6b Author: Vladimir Zapolskiy <[email protected]> AuthorDate: Thu, 22 Dec 2011 16:15:40 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 23 Dec 2011 11:58:34 +0100
oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue
This change fixes a linking problem, which happens if oprofile is selected to be compiled as built-in:
oprofile_arch_exit' referenced in section .init.text' of arch/arm/oprofile/built-in.o: defined in discarded section `.exit.text' of arch/arm/oprofile/built-in.o
The problem is appeared after commit 87121ca504, which introduced oprofile_arch_exit() calls from __init function. Note that the aforementioned commit has been backported to stable branches, and the problem is known to be reproduced at least with 3.0.13 and 3.1.5 kernels.
--- arch/arm/oprofile/common.c | 2 +- arch/sh/oprofile/common.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/oprofile/common.c +1 -1
@@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)return oprofile_perf_init (ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit (void ) {oprofile_perf_exit (); }
arch/sh/oprofile/common.c +2 -2
@@ -49,7 +49,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)return oprofile_perf_init (ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit (void ) {oprofile_perf_exit ();kfree (sh_pmu_op_name);
@@ -60,5 +60,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->backtrace = sh_backtrace; return -ENODEV; } -void __exit oprofile_arch_exit(void) {} +void oprofile_arch_exit (void ) {}#endif /* CONFIG_HW_PERF_EVENTS */