aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-19 12:17:29 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:08:52 -0400
commit5b249b1b07c42c61d0c53b8ab4fad026e39a9be9 (patch)
tree671b511c34bcae46b69dface3122f08d0ac399bf
parenta79f41ed9786b75ebe75e52295ad54049b8551b6 (diff)
pipe(2) - race-free error recovery
don't mess with sys_close() if copy_to_user() fails; just postpone fd_install() until we know it hasn't. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/pipe.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 8d85d7068c1e..bd3479db4b62 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1064,9 +1064,8 @@ err_inode:
1064 return err; 1064 return err;
1065} 1065}
1066 1066
1067int do_pipe_flags(int *fd, int flags) 1067static int __do_pipe_flags(int *fd, struct file **files, int flags)
1068{ 1068{
1069 struct file *files[2];
1070 int error; 1069 int error;
1071 int fdw, fdr; 1070 int fdw, fdr;
1072 1071
@@ -1088,11 +1087,8 @@ int do_pipe_flags(int *fd, int flags)
1088 fdw = error; 1087 fdw = error;
1089 1088
1090 audit_fd_pair(fdr, fdw); 1089 audit_fd_pair(fdr, fdw);
1091 fd_install(fdr, files[0]);
1092 fd_install(fdw, files[1]);
1093 fd[0] = fdr; 1090 fd[0] = fdr;
1094 fd[1] = fdw; 1091 fd[1] = fdw;
1095
1096 return 0; 1092 return 0;
1097 1093
1098 err_fdr: 1094 err_fdr:
@@ -1103,21 +1099,38 @@ int do_pipe_flags(int *fd, int flags)
1103 return error; 1099 return error;
1104} 1100}
1105 1101
1102int do_pipe_flags(int *fd, int flags)
1103{
1104 struct file *files[2];
1105 int error = __do_pipe_flags(fd, files, flags);
1106 if (!error) {
1107 fd_install(fd[0], files[0]);
1108 fd_install(fd[1], files[1]);
1109 }
1110 return error;
1111}
1112
1106/* 1113/*
1107 * sys_pipe() is the normal C calling standard for creating 1114 * sys_pipe() is the normal C calling standard for creating
1108 * a pipe. It's not the way Unix traditionally does this, though. 1115 * a pipe. It's not the way Unix traditionally does this, though.
1109 */ 1116 */
1110SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) 1117SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
1111{ 1118{
1119 struct file *files[2];
1112 int fd[2]; 1120 int fd[2];
1113 int error; 1121 int error;
1114 1122
1115 error = do_pipe_flags(fd, flags); 1123 error = __do_pipe_flags(fd, files, flags);
1116 if (!error) { 1124 if (!error) {
1117 if (copy_to_user(fildes, fd, sizeof(fd))) { 1125 if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
1118 sys_close(fd[0]); 1126 fput(files[0]);
1119 sys_close(fd[1]); 1127 fput(files[1]);
1128 put_unused_fd(fd[0]);
1129 put_unused_fd(fd[1]);
1120 error = -EFAULT; 1130 error = -EFAULT;
1131 } else {
1132 fd_install(fd[0], files[0]);
1133 fd_install(fd[1], files[1]);
1121 } 1134 }
1122 } 1135 }
1123 return error; 1136 return error;