aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2008-02-06 04:36:53 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:03 -0500
commit5e2cb1018a8a583b83d56c80f46507da6f3f2b57 (patch)
treeb9cbe718649c8be6e2d54aedcf75244fbe56bddd /kernel/time
parentbe6c28e62e3a304b74013afab029af2021e1f50d (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.c19
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)
363static ssize_t 363static ssize_t
364sysfs_show_current_clocksources(struct sys_device *dev, char *buf) 364sysfs_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
439sysfs_show_available_clocksources(struct sys_device *dev, char *buf) 437sysfs_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/*