Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 913050b

Browse files
Robert RichterIngo Molnar
authored andcommitted
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) Reported-By: Mike Waychison <[email protected]> Signed-off-by: Robert Richter <[email protected]> Cc: Andrew Morton <[email protected]> Cc: <[email protected]> Cc: oprofile-list <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 497f16f commit 913050b

3 files changed

Lines changed: 14 additions & 6 deletions

File tree

arch/s390/oprofile/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf,
8888
return -EINVAL;
8989

9090
retval = oprofilefs_ulong_from_user(&val, buf, count);
91-
if (retval)
91+
if (retval <= 0)
9292
return retval;
9393

9494
if (oprofile_started)

drivers/oprofile/oprofile_files.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf,
4545
return -EINVAL;
4646

4747
retval = oprofilefs_ulong_from_user(&val, buf, count);
48-
if (retval)
48+
if (retval <= 0)
4949
return retval;
5050

5151
retval = oprofile_set_timeout(val);
@@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou
8484
return -EINVAL;
8585

8686
retval = oprofilefs_ulong_from_user(&val, buf, count);
87-
if (retval)
87+
if (retval <= 0)
8888
return retval;
8989

9090
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 co
141141
return -EINVAL;
142142

143143
retval = oprofilefs_ulong_from_user(&val, buf, count);
144-
if (retval)
144+
if (retval <= 0)
145145
return retval;
146146

147+
retval = 0;
147148
if (val)
148149
retval = oprofile_start();
149150
else

drivers/oprofile/oprofilefs.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou
6060
}
6161

6262

63+
/*
64+
* Note: If oprofilefs_ulong_from_user() returns 0, then *val remains
65+
* unchanged and might be uninitialized. This follows write syscall
66+
* implementation when count is zero: "If count is zero ... [and if]
67+
* no errors are detected, 0 will be returned without causing any
68+
* other effect." (man 2 write)
69+
*/
6370
int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count)
6471
{
6572
char tmpbuf[TMPBUFSIZE];
@@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_
7986
raw_spin_lock_irqsave(&oprofilefs_lock, flags);
8087
*val = simple_strtoul(tmpbuf, NULL, 0);
8188
raw_spin_unlock_irqrestore(&oprofilefs_lock, flags);
82-
return 0;
89+
return count;
8390
}
8491

8592

@@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_
99106
return -EINVAL;
100107

101108
retval = oprofilefs_ulong_from_user(&value, buf, count);
102-
if (retval)
109+
if (retval <= 0)
103110
return retval;
104111

105112
retval = oprofile_set_ulong(file->private_data, value);

0 commit comments

Comments
 (0)