diff options
| author | Linus Torvalds <torvalds@linuxfoundation.org> | 2007-11-23 15:35:26 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linuxfoundation.org> | 2007-11-23 15:35:26 -0500 |
| commit | f68565831e7269e49b20f201ddef99f136a8c348 (patch) | |
| tree | 0e05cc22e5f1fea08113fd08549bf1e875abce9a /fs | |
| parent | bdd9c8e5286db0c47362e34a29fa1343fa83a4a6 (diff) | |
| download | tip-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.c | 18 | ||||
| -rw-r--r-- | fs/devices.c | 6 | ||||
| -rw-r--r-- | fs/file_table.c | 2 | ||||
| -rw-r--r-- | fs/open.c | 4 | ||||
| -rw-r--r-- | fs/proc/base.c | 18 | ||||
| -rw-r--r-- | fs/proc/generic.c | 7 | ||||
| -rw-r--r-- | fs/read_write.c | 14 |
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 */ |
