diff options
| -rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 2 | ||||
| -rw-r--r-- | arch/ia64/kernel/sys_ia64.c | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/syscall.c | 2 | ||||
| -rw-r--r-- | arch/parisc/hpux/sys_hpux.c | 2 | ||||
| -rw-r--r-- | arch/sh/kernel/sys_sh32.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 2 | ||||
| -rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 2 | ||||
| -rw-r--r-- | arch/x86/ia32/ia32entry.S | 1 | ||||
| -rw-r--r-- | arch/x86/ia32/sys_ia32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/syscall_table_32.S | 1 | ||||
| -rw-r--r-- | arch/xtensa/kernel/syscall.c | 2 | ||||
| -rw-r--r-- | fs/pipe.c | 23 | ||||
| -rw-r--r-- | include/asm-x86/unistd_32.h | 1 | ||||
| -rw-r--r-- | include/asm-x86/unistd_64.h | 2 | ||||
| -rw-r--r-- | include/linux/fs.h | 1 | 
15 files changed, 33 insertions, 14 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 7e028ceb93b..465116aecb8 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -1139,7 +1139,7 @@ sys32_pipe (int __user *fd)  	int retval;  	int fds[2]; -	retval = do_pipe(fds); +	retval = do_pipe_flags(fds, 0);  	if (retval)  		goto out;  	if (copy_to_user(fd, fds, sizeof(fds))) diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 1eda194b955..bcbb6d8792d 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -160,7 +160,7 @@ sys_pipe (void)  	int fd[2];  	int retval; -	retval = do_pipe(fd); +	retval = do_pipe_flags(fd, 0);  	if (retval)  		goto out;  	retval = fd[0]; diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 3523c8d12ed..343015a2f41 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -52,7 +52,7 @@ asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs)  	int fd[2];  	int error, res; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, 0);  	if (error) {  		res = error;  		goto out; diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index 0c5b9dabb47..be255ebb609 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c @@ -448,7 +448,7 @@ int hpux_pipe(int *kstack_fildes)  	int error;  	lock_kernel(); -	error = do_pipe(kstack_fildes); +	error = do_pipe_flags(kstack_fildes, 0);  	unlock_kernel();  	return error;  } diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index 125e493ead8..f0aa5c39865 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -29,7 +29,7 @@ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,  	int fd[2];  	int error; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, 0);  	if (!error) {  		regs->regs[1] = fd[1];  		return fd[0]; diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 3c6b49a53ae..4d73421559c 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -97,7 +97,7 @@ asmlinkage int sparc_pipe(struct pt_regs *regs)  	int fd[2];  	int error; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, 0);  	if (error)  		goto out;  	regs->u_regs[UREG_I1] = fd[1]; diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index e1f4eba2e57..39749e32dc7 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -418,7 +418,7 @@ asmlinkage long sparc_pipe(struct pt_regs *regs)  	int fd[2];  	int error; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, 0);  	if (error)  		goto out;  	regs->u_regs[UREG_I1] = fd[1]; diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 5614a8f7bed..18808b16457 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -830,4 +830,5 @@ ia32_sys_call_table:  	.quad sys_eventfd2  	.quad sys_epoll_create2  	.quad sys_dup3			/* 330 */ +	.quad sys_pipe2  ia32_syscall_end: diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index f00afdf61e6..d3c64088b98 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -238,7 +238,7 @@ asmlinkage long sys32_pipe(int __user *fd)  	int retval;  	int fds[2]; -	retval = do_pipe(fds); +	retval = do_pipe_flags(fds, 0);  	if (retval)  		goto out;  	if (copy_to_user(fd, fds, sizeof(fds))) diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index 24a3f1ea6a0..66154769d52 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -330,3 +330,4 @@ ENTRY(sys_call_table)  	.long sys_eventfd2  	.long sys_epoll_create2  	.long sys_dup3			/* 330 */ +	.long sys_pipe2 diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index f3e16efcd47..ac15ecbdf91 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -49,7 +49,7 @@ asmlinkage long xtensa_pipe(int __user *userfds)  	int fd[2];  	int error; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, 0);  	if (!error) {  		if (copy_to_user(userfds, fd, 2 * sizeof(int)))  			error = -EFAULT; diff --git a/fs/pipe.c b/fs/pipe.c index 700f4e0d957..68e82061070 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1027,12 +1027,15 @@ struct file *create_read_pipe(struct file *wrf)  	return f;  } -int do_pipe(int *fd) +int do_pipe_flags(int *fd, int flags)  {  	struct file *fw, *fr;  	int error;  	int fdw, fdr; +	if (flags & ~O_CLOEXEC) +		return -EINVAL; +  	fw = create_write_pipe();  	if (IS_ERR(fw))  		return PTR_ERR(fw); @@ -1041,12 +1044,12 @@ int do_pipe(int *fd)  	if (IS_ERR(fr))  		goto err_write_pipe; -	error = get_unused_fd(); +	error = get_unused_fd_flags(flags);  	if (error < 0)  		goto err_read_pipe;  	fdr = error; -	error = get_unused_fd(); +	error = get_unused_fd_flags(flags);  	if (error < 0)  		goto err_fdr;  	fdw = error; @@ -1074,16 +1077,21 @@ int do_pipe(int *fd)  	return error;  } +int do_pipe(int *fd) +{ +	return do_pipe_flags(fd, 0); +} +  /*   * sys_pipe() is the normal C calling standard for creating   * a pipe. It's not the way Unix traditionally does this, though.   */ -asmlinkage long __weak sys_pipe(int __user *fildes) +asmlinkage long __weak sys_pipe2(int __user *fildes, int flags)  {  	int fd[2];  	int error; -	error = do_pipe(fd); +	error = do_pipe_flags(fd, flags);  	if (!error) {  		if (copy_to_user(fildes, fd, sizeof(fd))) {  			sys_close(fd[0]); @@ -1094,6 +1102,11 @@ asmlinkage long __weak sys_pipe(int __user *fildes)  	return error;  } +asmlinkage long __weak sys_pipe(int __user *fildes) +{ +	return sys_pipe2(fildes, 0); +} +  /*   * pipefs should _never_ be mounted by userland - too much of security hassle,   * no real gain from having the whole whorehouse mounted. So we don't need diff --git a/include/asm-x86/unistd_32.h b/include/asm-x86/unistd_32.h index a1f6383bf69..748a05c77da 100644 --- a/include/asm-x86/unistd_32.h +++ b/include/asm-x86/unistd_32.h @@ -336,6 +336,7 @@  #define __NR_eventfd2		328  #define __NR_epoll_create2	329  #define __NR_dup3		330 +#define __NR_pipe2		331  #ifdef __KERNEL__ diff --git a/include/asm-x86/unistd_64.h b/include/asm-x86/unistd_64.h index f0fb2bd40cd..d2284b43ad5 100644 --- a/include/asm-x86/unistd_64.h +++ b/include/asm-x86/unistd_64.h @@ -649,6 +649,8 @@ __SYSCALL(__NR_eventfd2, sys_eventfd2)  __SYSCALL(__NR_epoll_create2, sys_epoll_create2)  #define __NR_dup3				292  __SYSCALL(__NR_dup3, sys_dup3) +#define __NR_pipe2				293 +__SYSCALL(__NR_pipe2, sys_pipe2)  #ifndef __NO_STUBS diff --git a/include/linux/fs.h b/include/linux/fs.h index e5e6a244096..0e80cd717d3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1777,6 +1777,7 @@ static inline void allow_write_access(struct file *file)  		atomic_inc(&file->f_path.dentry->d_inode->i_writecount);  }  extern int do_pipe(int *); +extern int do_pipe_flags(int *, int);  extern struct file *create_read_pipe(struct file *f);  extern struct file *create_write_pipe(void);  extern void free_write_pipe(struct file *);  |