From 06f49fe1674cf62d26f586c48b23d2bc1dc9b79f Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Tue, 17 Jul 2012 08:47:51 +0000 Subject: [PATCH] VFS: prevent buffer overflow If an FS returns faulty struct dirent data, VFS could overflow a buffer that holds this data. --- servers/vfs/path.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/servers/vfs/path.c b/servers/vfs/path.c index b3baf5815..bb9db3a2c 100644 --- a/servers/vfs/path.c +++ b/servers/vfs/path.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -545,9 +547,11 @@ struct vnode *dirp; struct vnode *entry; char ename[NAME_MAX + 1]; { +#define DIR_ENTRIES 8 +#define DIR_ENTRY_SIZE (sizeof(struct dirent) + NAME_MAX) u64_t pos, new_pos; - int r, consumed, totalbytes; - char buf[(sizeof(struct dirent) + NAME_MAX) * 8]; + int r, consumed, totalbytes, name_len; + char buf[DIR_ENTRY_SIZE * DIR_ENTRIES]; struct dirent *cur; pos = make64(0, 0); @@ -569,9 +573,14 @@ char ename[NAME_MAX + 1]; do { cur = (struct dirent *) (buf + consumed); + name_len = cur->d_reclen - offsetof(struct dirent, d_name) - 1; + + if(cur->d_name + name_len >= &buf[DIR_ENTRIES * DIR_ENTRY_SIZE]) + return(EINVAL); /* Rubbish in dir entry */ if (entry->v_inode_nr == cur->d_ino) { /* found the entry we were looking for */ - strlcpy(ename, cur->d_name, NAME_MAX+1); + strlcpy(ename, cur->d_name, + MIN(name_len + 1, NAME_MAX + 1)); ename[NAME_MAX] = '\0'; return(OK); } -- 2.44.0