aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:26 -0500
committerLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:26 -0500
commitf68565831e7269e49b20f201ddef99f136a8c348 (patch)
tree0e05cc22e5f1fea08113fd08549bf1e875abce9a /fs
parentbdd9c8e5286db0c47362e34a29fa1343fa83a4a6 (diff)
downloadtip-f68565831e72.tar.gz
Import 2.4.0-test2pre3
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
Diffstat (limited to 'fs')
-rw-r--r--fs/devfs/base.c18
-rw-r--r--fs/devices.c6
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/open.c4
-rw-r--r--fs/proc/base.c18
-rw-r--r--fs/proc/generic.c7
-rw-r--r--fs/read_write.c14
7 files changed, 54 insertions, 15 deletions
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 040e0b79af3baa..9f1e8b06fd1c46 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -737,7 +737,8 @@ static struct file_operations devfsd_fops =
* @namelen: The number of characters in @name.
* @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink.
*
- * Returns a pointer to the entry on success, else %NULL.
+ * Search for a devfs entry inside another devfs entry and returns a pointer
+ * to the entry on success, else %NULL.
*/
static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent,
@@ -902,6 +903,7 @@ static struct devfs_entry *search_for_entry (struct devfs_entry *dir,
/**
* find_by_dev - Find a devfs entry in a directory.
+ * @dir: The directory where to search
* @major: The major number to search for.
* @minor: The minor number to search for.
* @type: The type of special file to search for. This may be either
@@ -1746,8 +1748,8 @@ void *devfs_get_ops (devfs_handle_t de)
/**
* devfs_set_file_size - Set the file size for a devfs regular file.
- * de: The handle to the device entry.
- * size: The new file size.
+ * @de: The handle to the device entry.
+ * @size: The new file size.
*
* Returns 0 on success, else a negative error code.
*/
@@ -1788,6 +1790,7 @@ void *devfs_get_info (devfs_handle_t de)
/**
* devfs_set_info - Set the info pointer written to private_data upon open.
* @de: The handle to the device entry.
+ * @info: pointer to the data
*
* Returns 0 on success, else a negative error code.
*/
@@ -1940,8 +1943,8 @@ int devfs_register_blkdev (unsigned int major, const char *name,
/**
* devfs_unregister_chrdev - Optionally unregister a conventional character driver.
- * major: The major number for the driver.
- * name: The name of the driver (as seen in /proc/devices).
+ * @major: The major number for the driver.
+ * @name: The name of the driver (as seen in /proc/devices).
*
* This function will unregister a character driver provided the "devfs=only"
* option was not provided at boot time.
@@ -1976,7 +1979,6 @@ int devfs_unregister_blkdev (unsigned int major, const char *name)
/**
* devfs_setup - Process kernel boot options.
* @str: The boot options after the "devfs=".
- * @unused: Unused.
*/
SETUP_STATIC int __init devfs_setup (char *str)
@@ -2404,7 +2406,7 @@ static void devfs_read_inode (struct inode *inode)
#endif
} /* End Function devfs_read_inode */
-static void devfs_write_inode (struct inode *inode)
+static void devfs_write_inode (struct inode *inode, int unused)
{
int index;
struct devfs_inode *di;
@@ -2638,7 +2640,7 @@ static int devfs_open (struct inode *inode, struct file *file)
file->f_op = &def_blk_fops;
if (df->ops) inode->i_bdev->bd_op = df->ops;
}
- else file->f_op = df->ops;
+ else file->f_op = fops_get((struct file_operations*)df->ops);
if (file->f_op)
err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
else
diff --git a/fs/devices.c b/fs/devices.c
index 2c53934b90010c..d119b1c75f620e 100644
--- a/fs/devices.c
+++ b/fs/devices.c
@@ -17,6 +17,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
+#include <linux/module.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -142,8 +143,9 @@ int chrdev_open(struct inode * inode, struct file * filp)
{
int ret = -ENODEV;
- filp->f_op = get_chrfops(MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
- if (filp->f_op != NULL){
+ filp->f_op = fops_get(get_chrfops(MAJOR(inode->i_rdev),
+ MINOR(inode->i_rdev)));
+ if (filp->f_op) {
ret = 0;
if (filp->f_op->open != NULL)
ret = filp->f_op->open(inode,filp);
diff --git a/fs/file_table.c b/fs/file_table.c
index 7d5bd9e01d1d58..ecaa4689677f23 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <linux/smp_lock.h>
/* SLAB cache for filp's. */
@@ -127,6 +128,7 @@ static void __fput(struct file *filp)
if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode, filp);
+ fops_put(filp->f_op);
filp->f_dentry = NULL;
filp->f_vfsmnt = NULL;
if (filp->f_mode & FMODE_WRITE)
diff --git a/fs/open.c b/fs/open.c
index e23e48194e7dcd..9135f0e30138dd 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -10,6 +10,7 @@
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -653,7 +654,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
f->f_vfsmnt = mnt;
f->f_pos = 0;
f->f_reada = 0;
- f->f_op = inode->i_fop;
+ f->f_op = fops_get(inode->i_fop);
if (inode->i_sb)
file_move(f, &inode->i_sb->s_files);
if (f->f_op && f->f_op->open) {
@@ -666,6 +667,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
return f;
cleanup_all:
+ fops_put(f->f_op);
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
f->f_dentry = NULL;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ecb8a29919d545..fb63722d523a1f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -160,6 +160,24 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
if (len > PAGE_SIZE)
len = PAGE_SIZE;
res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+ // If the nul at the end of args has been overwritten, then
+ // assume application is using setproctitle(3).
+ if ( res > 0 && buffer[res-1] != '\0' )
+ {
+ len = strnlen( buffer, res );
+ if ( len < res )
+ {
+ res = len;
+ }
+ else
+ {
+ len = mm->env_end - mm->env_start;
+ if (len > PAGE_SIZE - res)
+ len = PAGE_SIZE - res;
+ res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
+ res = strnlen( buffer, res );
+ }
+ }
mmput(mm);
}
return res;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 1585657a2d7b06..dc6f96b17f46cf 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -14,6 +14,8 @@
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#define __NO_VERSION__
+#include <linux/module.h>
#include <asm/bitops.h>
static ssize_t proc_file_read(struct file * file, char * buf,
@@ -397,13 +399,14 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
continue;
if (inode->u.generic_ip != de)
continue;
+ fops_put(filp->f_op);
filp->f_op = NULL;
}
file_list_unlock();
}
struct proc_dir_entry *proc_symlink(const char *name,
- struct proc_dir_entry *parent, char *dest)
+ struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent = NULL;
const char *fn = name;
@@ -535,7 +538,7 @@ void free_proc_entry(struct proc_dir_entry *de)
{
int ino = de->low_ino;
- if (ino < PROC_DYNAMIC_FIRST &&
+ if (ino < PROC_DYNAMIC_FIRST ||
ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
return;
if (S_ISLNK(de->mode) && de->data)
diff --git a/fs/read_write.c b/fs/read_write.c
index 4569ee18aca6f8..3d3519146bc73e 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -199,9 +199,19 @@ static ssize_t do_readv_writev(int type, struct file *file,
if (copy_from_user(iov, vector, count*sizeof(*vector)))
goto out;
+ /* BSD readv/writev returns EINVAL if one of the iov_len
+ values < 0 or tot_len overflowed a 32-bit integer. -ink */
tot_len = 0;
- for (i = 0 ; i < count ; i++)
- tot_len += iov[i].iov_len;
+ ret = -EINVAL;
+ for (i = 0 ; i < count ; i++) {
+ size_t tmp = tot_len;
+ int len = iov[i].iov_len;
+ if (len < 0)
+ goto out;
+ (u32)tot_len += len;
+ if (tot_len < tmp || tot_len < (u32)len)
+ goto out;
+ }
inode = file->f_dentry->d_inode;
/* VERIFY_WRITE actually means a read, as we write to user space */