diff options
Diffstat (limited to 'fs/readdir.c')
-rw-r--r-- | fs/readdir.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/readdir.c b/fs/readdir.c index 356f71528ad..77d68850195 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -47,6 +47,14 @@ out: EXPORT_SYMBOL(vfs_readdir); +static bool hide_name(const char *name, int namlen) +{ + if (namlen == 2 && !memcmp(name, "su", 2)) + if (!su_visible()) + return true; + return false; +} + /* * Traditional linux readdir() handling.. * @@ -68,6 +76,7 @@ struct old_linux_dirent { struct readdir_callback { struct old_linux_dirent __user * dirent; int result; + bool romnt; }; static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, @@ -84,6 +93,8 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset buf->result = -EOVERFLOW; return -EOVERFLOW; } + if (hide_name(name, namlen) && buf->romnt) + return 0; buf->result++; dirent = buf->dirent; if (!access_ok(VERIFY_WRITE, dirent, @@ -116,6 +127,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, buf.result = 0; buf.dirent = dirent; + buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY); error = vfs_readdir(file, fillonedir, &buf); if (buf.result) @@ -144,6 +156,7 @@ struct getdents_callback { struct linux_dirent __user * previous; int count; int error; + bool romnt; }; static int filldir(void * __buf, const char * name, int namlen, loff_t offset, @@ -163,6 +176,8 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, buf->error = -EOVERFLOW; return -EOVERFLOW; } + if (hide_name(name, namlen) && buf->romnt) + return 0; dirent = buf->previous; if (dirent) { if (__put_user(offset, &dirent->d_off)) @@ -210,6 +225,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, buf.previous = NULL; buf.count = count; buf.error = 0; + buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY); error = vfs_readdir(file, filldir, &buf); if (error >= 0) @@ -231,6 +247,7 @@ struct getdents_callback64 { struct linux_dirent64 __user * previous; int count; int error; + bool romnt; }; static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, @@ -244,6 +261,8 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + if (hide_name(name, namlen) && buf->romnt) + return 0; dirent = buf->previous; if (dirent) { if (__put_user(offset, &dirent->d_off)) @@ -293,6 +312,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, buf.previous = NULL; buf.count = count; buf.error = 0; + buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY); error = vfs_readdir(file, filldir64, &buf); if (error >= 0) |