diff options
| author | Miao Xie <miaox@cn.fujitsu.com> | 2008-02-06 04:36:53 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:03 -0500 |
| commit | 5e2cb1018a8a583b83d56c80f46507da6f3f2b57 (patch) | |
| tree | b9cbe718649c8be6e2d54aedcf75244fbe56bddd /kernel/time | |
| parent | be6c28e62e3a304b74013afab029af2021e1f50d (diff) | |
time: fix sysfs_show_{available,current}_clocksources() buffer overflow problem
I found that there is a buffer overflow problem in the following code.
Version: 2.6.24-rc2,
File: kernel/time/clocksource.c:417-432
--------------------------------------------------------------------
static ssize_t
sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
{
struct clocksource *src;
char *curr = buf;
spin_lock_irq(&clocksource_lock);
list_for_each_entry(src, &clocksource_list, list) {
curr += sprintf(curr, "%s ", src->name);
}
spin_unlock_irq(&clocksource_lock);
curr += sprintf(curr, "\n");
return curr - buf;
}
-----------------------------------------------------------------------
sysfs_show_current_clocksources() also has the same problem though in practice
the size of current clocksource's name won't exceed PAGE_SIZE.
I fix the bug by using snprintf according to the specification of the kernel
(Version:2.6.24-rc2,File:Documentation/filesystems/sysfs.txt)
Fix sysfs_show_available_clocksources() and sysfs_show_current_clocksources()
buffer overflow problem with snprintf().
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: john stultz <johnstul@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/clocksource.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 6e9259a5d501..81afb3927ecc 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
| @@ -363,15 +363,13 @@ void clocksource_unregister(struct clocksource *cs) | |||
| 363 | static ssize_t | 363 | static ssize_t |
| 364 | sysfs_show_current_clocksources(struct sys_device *dev, char *buf) | 364 | sysfs_show_current_clocksources(struct sys_device *dev, char *buf) |
| 365 | { | 365 | { |
| 366 | char *curr = buf; | 366 | ssize_t count = 0; |
| 367 | 367 | ||
| 368 | spin_lock_irq(&clocksource_lock); | 368 | spin_lock_irq(&clocksource_lock); |
| 369 | curr += sprintf(curr, "%s ", curr_clocksource->name); | 369 | count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name); |
| 370 | spin_unlock_irq(&clocksource_lock); | 370 | spin_unlock_irq(&clocksource_lock); |
| 371 | 371 | ||
| 372 | curr += sprintf(curr, "\n"); | 372 | return count; |
| 373 | |||
| 374 | return curr - buf; | ||
| 375 | } | 373 | } |
| 376 | 374 | ||
| 377 | /** | 375 | /** |
| @@ -439,17 +437,20 @@ static ssize_t | |||
| 439 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) | 437 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) |
| 440 | { | 438 | { |
| 441 | struct clocksource *src; | 439 | struct clocksource *src; |
| 442 | char *curr = buf; | 440 | ssize_t count = 0; |
| 443 | 441 | ||
| 444 | spin_lock_irq(&clocksource_lock); | 442 | spin_lock_irq(&clocksource_lock); |
| 445 | list_for_each_entry(src, &clocksource_list, list) { | 443 | list_for_each_entry(src, &clocksource_list, list) { |
| 446 | curr += sprintf(curr, "%s ", src->name); | 444 | count += snprintf(buf + count, |
| 445 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), | ||
| 446 | "%s ", src->name); | ||
| 447 | } | 447 | } |
| 448 | spin_unlock_irq(&clocksource_lock); | 448 | spin_unlock_irq(&clocksource_lock); |
| 449 | 449 | ||
| 450 | curr += sprintf(curr, "\n"); | 450 | count += snprintf(buf + count, |
| 451 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n"); | ||
| 451 | 452 | ||
| 452 | return curr - buf; | 453 | return count; |
| 453 | } | 454 | } |
| 454 | 455 | ||
| 455 | /* | 456 | /* |
