return err;
}
-int do_pipe_flags(int *fd, int flags)
+static int __do_pipe_flags(int *fd, struct file **files, int flags)
{
- struct file *files[2];
int error;
int fdw, fdr;
fdw = error;
audit_fd_pair(fdr, fdw);
- fd_install(fdr, files[0]);
- fd_install(fdw, files[1]);
fd[0] = fdr;
fd[1] = fdw;
-
return 0;
err_fdr:
return error;
}
+int do_pipe_flags(int *fd, int flags)
+{
+ struct file *files[2];
+ int error = __do_pipe_flags(fd, files, flags);
+ if (!error) {
+ fd_install(fd[0], files[0]);
+ fd_install(fd[1], files[1]);
+ }
+ return error;
+}
+
/*
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way Unix traditionally does this, though.
*/
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
{
+ struct file *files[2];
int fd[2];
int error;
- error = do_pipe_flags(fd, flags);
+ error = __do_pipe_flags(fd, files, flags);
if (!error) {
- if (copy_to_user(fildes, fd, sizeof(fd))) {
- sys_close(fd[0]);
- sys_close(fd[1]);
+ if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
+ fput(files[0]);
+ fput(files[1]);
+ put_unused_fd(fd[0]);
+ put_unused_fd(fd[1]);
error = -EFAULT;
+ } else {
+ fd_install(fd[0], files[0]);
+ fd_install(fd[1], files[1]);
}
}
return error;