aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/net/socket.c b/net/socket.c
index 0778c5442411..9566e57ac7f5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1194,6 +1194,7 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1194{ 1194{
1195 struct socket *sock1, *sock2; 1195 struct socket *sock1, *sock2;
1196 int fd1, fd2, err; 1196 int fd1, fd2, err;
1197 struct file *newfile1, *newfile2;
1197 1198
1198 /* 1199 /*
1199 * Obtain the first socket and check if the underlying protocol 1200 * Obtain the first socket and check if the underlying protocol
@@ -1212,18 +1213,37 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1212 if (err < 0) 1213 if (err < 0)
1213 goto out_release_both; 1214 goto out_release_both;
1214 1215
1215 fd1 = fd2 = -1; 1216 fd1 = sock_alloc_fd(&newfile1);
1217 if (unlikely(fd1 < 0))
1218 goto out_release_both;
1216 1219
1217 err = sock_map_fd(sock1); 1220 fd2 = sock_alloc_fd(&newfile2);
1218 if (err < 0) 1221 if (unlikely(fd2 < 0)) {
1222 put_filp(newfile1);
1223 put_unused_fd(fd1);
1219 goto out_release_both; 1224 goto out_release_both;
1220 fd1 = err; 1225 }
1221 1226
1222 err = sock_map_fd(sock2); 1227 err = sock_attach_fd(sock1, newfile1);
1223 if (err < 0) 1228 if (unlikely(err < 0)) {
1224 goto out_close_1; 1229 goto out_fd2;
1225 fd2 = err; 1230 }
1231
1232 err = sock_attach_fd(sock2, newfile2);
1233 if (unlikely(err < 0)) {
1234 fput(newfile1);
1235 goto out_fd1;
1236 }
1237
1238 err = audit_fd_pair(fd1, fd2);
1239 if (err < 0) {
1240 fput(newfile1);
1241 fput(newfile2);
1242 goto out_fd;
1243 }
1226 1244
1245 fd_install(fd1, newfile1);
1246 fd_install(fd2, newfile2);
1227 /* fd1 and fd2 may be already another descriptors. 1247 /* fd1 and fd2 may be already another descriptors.
1228 * Not kernel problem. 1248 * Not kernel problem.
1229 */ 1249 */
@@ -1238,17 +1258,23 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
1238 sys_close(fd1); 1258 sys_close(fd1);
1239 return err; 1259 return err;
1240 1260
1241out_close_1:
1242 sock_release(sock2);
1243 sys_close(fd1);
1244 return err;
1245
1246out_release_both: 1261out_release_both:
1247 sock_release(sock2); 1262 sock_release(sock2);
1248out_release_1: 1263out_release_1:
1249 sock_release(sock1); 1264 sock_release(sock1);
1250out: 1265out:
1251 return err; 1266 return err;
1267
1268out_fd2:
1269 put_filp(newfile1);
1270 sock_release(sock1);
1271out_fd1:
1272 put_filp(newfile2);
1273 sock_release(sock2);
1274out_fd:
1275 put_unused_fd(fd1);
1276 put_unused_fd(fd2);
1277 goto out;
1252} 1278}
1253 1279
1254/* 1280/*