* [PATCH] fs: Check fsname's length in get_filesystem_list().
@ 2009-04-09 11:18 Tetsuo Handa
2009-04-09 21:02 ` Al Viro
0 siblings, 1 reply; 2+ messages in thread
From: Tetsuo Handa @ 2009-04-09 11:18 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel
Since "struct file_system_type"->name does not limit the max length,
one might pass a name with strlen(name) >= 80.
while (tmp && len < PAGE_SIZE - 80) {
len += sprintf(buf+len, "%s\t%s\n",
(tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
tmp->name);
This can cause buffer overrun if somebody builts in very very long filesystem
name (as shown in example code below); although unlikely happens, for
get_filesystem_list() is called only once upon boot.
----- dummyfs.c start : Build with obj-y += dummyfs.o -----
#include <linux/fs.h>
#include <linux/init.h>
static char name[PAGE_SIZE * 16];
static int dummy_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
struct vfsmount *mnt)
{
return -ENOMEM;
}
static struct file_system_type dummy_fs_type = {
.name = name,
.get_sb = dummy_get_sb,
.kill_sb = kill_litter_super,
};
static int __init dummyfs_init(void)
{
memset(name, 'X', sizeof(name));
name[sizeof(name) - 1] = '\0';
return register_filesystem(&dummy_fs_type);
}
__initcall(dummyfs_init);
----- dummyfs.c end -----
----------
[PATCH] fs: Check fsname's length in get_filesystem_list().
Since "struct file_system_type"->name does not limit the max length,
one can pass a name with strlen(name) >= 80.
This can cause buffer overrun; although unlikely happens, for
get_filesystem_list() is called only once upon boot.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
fs/filesystems.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
--- linux-2.6.30-rc1.orig/fs/filesystems.c
+++ linux-2.6.30-rc1/fs/filesystems.c
@@ -202,15 +202,17 @@ SYSCALL_DEFINE3(sysfs, int, option, unsi
int __init get_filesystem_list(char *buf)
{
int len = 0;
- struct file_system_type * tmp;
+ struct file_system_type *tmp;
read_lock(&file_systems_lock);
- tmp = file_systems;
- while (tmp && len < PAGE_SIZE - 80) {
- len += sprintf(buf+len, "%s\t%s\n",
- (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
- tmp->name);
- tmp = tmp->next;
+ for (tmp = file_systems; tmp; tmp = tmp->next) {
+ /* 8 is for "nodev" + '\t' + '\n' + '\0'. */
+ const int n = strlen(tmp->name) + 8;
+ if (len + n >= PAGE_SIZE)
+ break;
+ len += sprintf(buf + len, "%s\t%s\n",
+ (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
+ tmp->name);
}
read_unlock(&file_systems_lock);
return len;
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] fs: Check fsname's length in get_filesystem_list().
2009-04-09 11:18 [PATCH] fs: Check fsname's length in get_filesystem_list() Tetsuo Handa
@ 2009-04-09 21:02 ` Al Viro
0 siblings, 0 replies; 2+ messages in thread
From: Al Viro @ 2009-04-09 21:02 UTC (permalink / raw)
To: Tetsuo Handa; +Cc: linux-fsdevel
On Thu, Apr 09, 2009 at 08:18:11PM +0900, Tetsuo Handa wrote:
> Since "struct file_system_type"->name does not limit the max length,
> one might pass a name with strlen(name) >= 80.
>
> while (tmp && len < PAGE_SIZE - 80) {
> len += sprintf(buf+len, "%s\t%s\n",
> (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
> tmp->name);
>
> This can cause buffer overrun if somebody builts in very very long filesystem
> name (as shown in example code below); although unlikely happens, for
> get_filesystem_list() is called only once upon boot.
Doctor, it hurts when I do it...
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-04-09 21:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-09 11:18 [PATCH] fs: Check fsname's length in get_filesystem_list() Tetsuo Handa
2009-04-09 21:02 ` Al Viro
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).