The patch titled file: modify struct fown_struct to use a struct pid has been added to the -mm tree. Its filename is file-modify-struct-fown_struct-to-use-a-struct-pid.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: file: modify struct fown_struct to use a struct pid From: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> File handles can be requested to send sigio and sigurg to processes. By tracking the destination processes using struct pid instead of pid_t we make the interface safe from all potential pid wrap around problems. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/net/tun.c | 2 - fs/dnotify.c | 2 - fs/fcntl.c | 77 +++++++++++++++++++++++++++---------------- fs/file_table.c | 1 fs/locks.c | 2 - include/linux/fs.h | 5 ++ kernel/futex.c | 2 - net/socket.c | 2 - 8 files changed, 59 insertions(+), 34 deletions(-) diff -puN drivers/net/tun.c~file-modify-struct-fown_struct-to-use-a-struct-pid drivers/net/tun.c --- a/drivers/net/tun.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/drivers/net/tun.c @@ -697,7 +697,7 @@ static int tun_chr_fasync(int fd, struct return ret; if (on) { - ret = f_setown(file, current->pid, 0); + ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); if (ret) return ret; tun->flags |= TUN_FASYNC; diff -puN fs/dnotify.c~file-modify-struct-fown_struct-to-use-a-struct-pid fs/dnotify.c --- a/fs/dnotify.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/fs/dnotify.c @@ -92,7 +92,7 @@ int fcntl_dirnotify(int fd, struct file prev = &odn->dn_next; } - error = f_setown(filp, current->pid, 0); + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); if (error) goto out_free; diff -puN fs/fcntl.c~file-modify-struct-fown_struct-to-use-a-struct-pid fs/fcntl.c --- a/fs/fcntl.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/fs/fcntl.c @@ -250,19 +250,22 @@ static int setfl(int fd, struct file * f return error; } -static void f_modown(struct file *filp, unsigned long pid, +static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, uid_t uid, uid_t euid, int force) { write_lock_irq(&filp->f_owner.lock); if (force || !filp->f_owner.pid) { - filp->f_owner.pid = pid; + put_pid(filp->f_owner.pid); + filp->f_owner.pid = get_pid(pid); + filp->f_owner.pid_type = type; filp->f_owner.uid = uid; filp->f_owner.euid = euid; } write_unlock_irq(&filp->f_owner.lock); } -int f_setown(struct file *filp, unsigned long arg, int force) +int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, + int force) { int err; @@ -270,15 +273,42 @@ int f_setown(struct file *filp, unsigned if (err) return err; - f_modown(filp, arg, current->uid, current->euid, force); + f_modown(filp, pid, type, current->uid, current->euid, force); return 0; } +EXPORT_SYMBOL(__f_setown); +int f_setown(struct file *filp, unsigned long arg, int force) +{ + enum pid_type type; + struct pid *pid; + int who = arg; + int result; + type = PIDTYPE_PID; + if (who < 0) { + type = PIDTYPE_PGID; + who = -who; + } + rcu_read_lock(); + pid = find_pid(who); + result = __f_setown(filp, pid, type, force); + rcu_read_unlock(); + return result; +} EXPORT_SYMBOL(f_setown); void f_delown(struct file *filp) { - f_modown(filp, 0, 0, 0, 1); + f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1); +} + +pid_t f_getown(struct file *filp) +{ + pid_t pid; + pid = pid_nr(filp->f_owner.pid); + if (sock->file->f_owner.pid_type == PIDTYPE_PGID) + pid = -pid; + return pid; } static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, @@ -319,7 +349,7 @@ static long do_fcntl(int fd, unsigned in * current syscall conventions, the only way * to fix this will be in libc. */ - err = filp->f_owner.pid; + err = f_getown(filp); force_successful_syscall_return(); break; case F_SETOWN: @@ -470,24 +500,19 @@ static void send_sigio_to_task(struct ta void send_sigio(struct fown_struct *fown, int fd, int band) { struct task_struct *p; - int pid; + enum pid_type type; + struct pid *pid; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigio_to_task(p, fown, fd, band); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigio_to_task(p, fown, fd, band); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigio_to_task(p, fown, fd, band); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); @@ -503,9 +528,12 @@ static void send_sigurg_to_task(struct t int send_sigurg(struct fown_struct *fown) { struct task_struct *p; - int pid, ret = 0; + enum pid_type type; + struct pid *pid; + int ret = 0; read_lock(&fown->lock); + type = fown->pid_type; pid = fown->pid; if (!pid) goto out_unlock_fown; @@ -513,16 +541,9 @@ int send_sigurg(struct fown_struct *fown ret = 1; read_lock(&tasklist_lock); - if (pid > 0) { - p = find_task_by_pid(pid); - if (p) { - send_sigurg_to_task(p, fown); - } - } else { - do_each_task_pid(-pid, PIDTYPE_PGID, p) { - send_sigurg_to_task(p, fown); - } while_each_task_pid(-pid, PIDTYPE_PGID, p); - } + do_each_pid_task(pid, type, p) { + send_sigurg_to_task(p, fown); + } while_each_pid_task(pid, type, p); read_unlock(&tasklist_lock); out_unlock_fown: read_unlock(&fown->lock); diff -puN fs/file_table.c~file-modify-struct-fown_struct-to-use-a-struct-pid fs/file_table.c --- a/fs/file_table.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/fs/file_table.c @@ -174,6 +174,7 @@ void fastcall __fput(struct file *file) fops_put(file->f_op); if (file->f_mode & FMODE_WRITE) put_write_access(inode); + put_pid(file->f_owner.pid); file_kill(file); file->f_dentry = NULL; file->f_vfsmnt = NULL; diff -puN fs/locks.c~file-modify-struct-fown_struct-to-use-a-struct-pid fs/locks.c --- a/fs/locks.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/fs/locks.c @@ -1514,7 +1514,7 @@ int fcntl_setlease(unsigned int fd, stru goto out_unlock; } - error = f_setown(filp, current->pid, 0); + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); out_unlock: unlock_kernel(); return error; diff -puN include/linux/fs.h~file-modify-struct-fown_struct-to-use-a-struct-pid include/linux/fs.h --- a/include/linux/fs.h~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/include/linux/fs.h @@ -667,7 +667,8 @@ extern struct block_device *I_BDEV(struc struct fown_struct { rwlock_t lock; /* protects pid, uid, euid fields */ - int pid; /* pid or -pgrp where SIGIO should be sent */ + struct pid *pid; /* pid or -pgrp where SIGIO should be sent */ + enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */ uid_t uid, euid; /* uid/euid of process setting the owner */ int signum; /* posix.1b rt signal to be delivered on IO */ }; @@ -863,8 +864,10 @@ extern void kill_fasync(struct fasync_st /* only for net: no internal synchronization */ extern void __kill_fasync(struct fasync_struct *, int, int); +extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern int f_setown(struct file *filp, unsigned long arg, int force); extern void f_delown(struct file *filp); +extern pid_t f_getown(struct file *filp); extern int send_sigurg(struct fown_struct *fown); /* diff -puN kernel/futex.c~file-modify-struct-fown_struct-to-use-a-struct-pid kernel/futex.c --- a/kernel/futex.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/kernel/futex.c @@ -1589,7 +1589,7 @@ static int futex_fd(u32 __user *uaddr, i filp->f_mapping = filp->f_dentry->d_inode->i_mapping; if (signal) { - err = f_setown(filp, current->pid, 1); + err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1); if (err < 0) { goto error; } diff -puN net/socket.c~file-modify-struct-fown_struct-to-use-a-struct-pid net/socket.c --- a/net/socket.c~file-modify-struct-fown_struct-to-use-a-struct-pid +++ a/net/socket.c @@ -825,7 +825,7 @@ static long sock_ioctl(struct file *file break; case FIOGETOWN: case SIOCGPGRP: - err = put_user(sock->file->f_owner.pid, + err = put_user(f_getown(sock->file), (int __user *)argp); break; case SIOCGIFBR: _ Patches currently in -mm which might be from ebiederm@xxxxxxxxxxxx are megaraid-use-the-proper-type-to-hold-the-irq-number.patch x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch msi-use-kmem_cache_zalloc.patch sysctl-allow-proc-sys-without-sys_sysctl.patch sysctl-scream-if-someone-uses-sys_sysctl.patch sysctl-document-that-sys_sysctl-will-be-removed.patch pid-implement-transfer_pid-and-use-it-to-simplify-de_thread.patch pid-remove-temporary-debug-code-in-attach_pid.patch de_thread-use-tsk-not-current.patch pidspace-is_init.patch stack-overflow-safe-kdump-safe_smp_processor_id.patch stack-overflow-safe-kdump-safe_smp_processor_id_voyager.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id-fix.patch stack-overflow-safe-kdump-safe_smp_send_nmi_allbutself.patch proc-reorder-the-functions-in-basec.patch proc-modify-proc_pident_lookup-to-be-completely-table-driven.patch proc-give-the-root-directory-a-task.patch proc-make-the-generation-of-the-self-symlink-table-driven.patch proc-factor-out-an-instantiate-method-from-every-lookup-method.patch proc-remove-the-hard-coded-inode-numbers.patch proc-merge-proc_tid_attr-and-proc_tgid_attr.patch pid-implement-access-helpers-for-a-tacks-various-process-groups.patch pid-add-do_each_pid_task.patch pid-implement-signal-functions-that-take-a-struct-pid.patch pid-export-the-symbols-needed-to-use-struct-pid.patch pid-implement-pid_nr.patch vt-update-spawnpid-to-be-a-struct-pid_t.patch file-modify-struct-fown_struct-to-use-a-struct-pid.patch proc-sysctl-add-_proc_do_string-helper.patch namespaces-add-nsproxy.patch namespaces-add-nsproxy-dont-include-compileh.patch namespaces-incorporate-fs-namespace-into-nsproxy.patch namespaces-utsname-introduce-temporary-helpers.patch namespaces-utsname-switch-to-using-uts-namespaces.patch namespaces-utsname-use-init_utsname-when-appropriate.patch namespaces-utsname-implement-utsname-namespaces.patch namespaces-utsname-sysctl-hack.patch namespaces-utsname-remove-system_utsname.patch namespaces-utsname-implement-clone_newuts-flag.patch uts-copy-nsproxy-only-when-needed.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit.patch namespaces-utsname-use-init_utsname-when-appropriate-klibc-bit.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit-2.patch ipc-namespace-core.patch ipc-namespace-utils.patch genirq-irq-convert-the-move_irq-flag-from-a-32bit-word-to-a-single-bit.patch genirq-irq-add-moved_masked_irq.patch genirq-x86_64-irq-reenable-migrating-irqs-to-other-cpus.patch genirq-msi-simplify-msi-enable-and-disable.patch genirq-msi-make-the-msi-boolean-tests-return-either-0-or-1.patch genirq-msi-implement-helper-functions-read_msi_msg-and-write_msi_msg.patch genirq-msi-refactor-the-msi_ops.patch genirq-msi-simplify-the-msi-irq-limit-policy.patch genirq-irq-add-a-dynamic-irq-creation-api.patch genirq-ia64-irq-dynamic-irq-support.patch genirq-i386-irq-dynamic-irq-support.patch genirq-x86_64-irq-dynamic-irq-support.patch genirq-msi-make-the-msi-code-irq-based-and-not-vector-based.patch genirq-x86_64-irq-move-msi-message-composition-into-io_apicc.patch genirq-i386-irq-move-msi-message-composition-into-io_apicc.patch genirq-msi-only-build-msi-apicc-on-ia64.patch genirq-msi-only-build-msi-apicc-on-ia64-fix.patch genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-irq-remove-msi-hacks.patch genirq-irq-generalize-the-check-for-hardirq_bits.patch genirq-x86_64-irq-make-the-external-irq-handlers-report-their-vector-not-the-irq-number.patch genirq-x86_64-irq-make-vector_irq-per-cpu.patch genirq-x86_64-irq-make-vector_irq-per-cpu-fix.patch genirq-x86_64-irq-make-vector_irq-per-cpu-warning-fix.patch genirq-x86_64-irq-kill-gsi_irq_sharing.patch genirq-x86_64-irq-kill-irq-compression.patch add-hypertransport-capability-defines.patch add-hypertransport-capability-defines-fix.patch initial-generic-hypertransport-interrupt-support.patch initial-generic-hypertransport-interrupt-support-Kconfig-fix.patch pidhash-temporary-debug-checks.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html