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 | |
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')
-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 | /* |