Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs update from Al Viro:

 - big one - consolidation of descriptor-related logics; almost all of
   that is moved to fs/file.c

   (BTW, I'm seriously tempted to rename the result to fd.c.  As it is,
   we have a situation when file_table.c is about handling of struct
   file and file.c is about handling of descriptor tables; the reasons
   are historical - file_table.c used to be about a static array of
   struct file we used to have way back).

   A lot of stray ends got cleaned up and converted to saner primitives,
   disgusting mess in android/binder.c is still disgusting, but at least
   doesn't poke so much in descriptor table guts anymore.  A bunch of
   relatively minor races got fixed in process, plus an ext4 struct file
   leak.

 - related thing - fget_light() partially unuglified; see fdget() in
   there (and yes, it generates the code as good as we used to have).

 - also related - bits of Cyrill's procfs stuff that got entangled into
   that work; _not_ all of it, just the initial move to fs/proc/fd.c and
   switch of fdinfo to seq_file.

 - Alex's fs/coredump.c spiltoff - the same story, had been easier to
   take that commit than mess with conflicts.  The rest is a separate
   pile, this was just a mechanical code movement.

 - a few misc patches all over the place.  Not all for this cycle,
   there'll be more (and quite a few currently sit in akpm's tree)."

Fix up trivial conflicts in the android binder driver, and some fairly
simple conflicts due to two different changes to the sock_alloc_file()
interface ("take descriptor handling from sock_alloc_file() to callers"
vs "net: Providing protocol type via system.sockprotoname xattr of
/proc/PID/fd entries" adding a dentry name to the socket)

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits)
  MAX_LFS_FILESIZE should be a loff_t
  compat: fs: Generic compat_sys_sendfile implementation
  fs: push rcu_barrier() from deactivate_locked_super() to filesystems
  btrfs: reada_extent doesn't need kref for refcount
  coredump: move core dump functionality into its own file
  coredump: prevent double-free on an error path in core dumper
  usb/gadget: fix misannotations
  fcntl: fix misannotations
  ceph: don't abuse d_delete() on failure exits
  hypfs: ->d_parent is never NULL or negative
  vfs: delete surplus inode NULL check
  switch simple cases of fget_light to fdget
  new helpers: fdget()/fdput()
  switch o2hb_region_dev_write() to fget_light()
  proc_map_files_readdir(): don't bother with grabbing files
  make get_file() return its argument
  vhost_set_vring(): turn pollstart/pollstop into bool
  switch prctl_set_mm_exe_file() to fget_light()
  switch xfs_find_handle() to fget_light()
  switch xfs_swapext() to fget_light()
  ...
This commit is contained in:
Linus Torvalds 2012-10-02 20:25:04 -07:00
commit aab174f0df
142 changed files with 2915 additions and 2877 deletions

View file

@ -2088,15 +2088,19 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
return (atsecure || cap_bprm_secureexec(bprm));
}
static int match_file(const void *p, struct file *file, unsigned fd)
{
return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
}
/* Derived from fs/exec.c:flush_old_files. */
static inline void flush_unauthorized_files(const struct cred *cred,
struct files_struct *files)
{
struct file *file, *devnull = NULL;
struct tty_struct *tty;
struct fdtable *fdt;
long j = -1;
int drop_tty = 0;
unsigned n;
tty = get_current_tty();
if (tty) {
@ -2123,58 +2127,23 @@ static inline void flush_unauthorized_files(const struct cred *cred,
no_tty();
/* Revalidate access to inherited open files. */
spin_lock(&files->file_lock);
for (;;) {
unsigned long set, i;
int fd;
j++;
i = j * BITS_PER_LONG;
fdt = files_fdtable(files);
if (i >= fdt->max_fds)
break;
set = fdt->open_fds[j];
if (!set)
continue;
spin_unlock(&files->file_lock);
for ( ; set ; i++, set >>= 1) {
if (set & 1) {
file = fget(i);
if (!file)
continue;
if (file_has_perm(cred,
file,
file_to_av(file))) {
sys_close(i);
fd = get_unused_fd();
if (fd != i) {
if (fd >= 0)
put_unused_fd(fd);
fput(file);
continue;
}
if (devnull) {
get_file(devnull);
} else {
devnull = dentry_open(
&selinux_null,
O_RDWR, cred);
if (IS_ERR(devnull)) {
devnull = NULL;
put_unused_fd(fd);
fput(file);
continue;
}
}
fd_install(fd, devnull);
}
fput(file);
}
}
spin_lock(&files->file_lock);
n = iterate_fd(files, 0, match_file, cred);
if (!n) /* none found? */
return;
devnull = dentry_open(&selinux_null, O_RDWR, cred);
if (!IS_ERR(devnull)) {
/* replace all the matching ones with this */
do {
replace_fd(n - 1, get_file(devnull), 0);
} while ((n = iterate_fd(files, n, match_file, cred)) != 0);
fput(devnull);
} else {
/* just close all the matching ones */
do {
replace_fd(n - 1, NULL, 0);
} while ((n = iterate_fd(files, n, match_file, cred)) != 0);
}
spin_unlock(&files->file_lock);
}
/*