Fix a fd leak in socketpair():

- Close the new file objects created during socketpair() if the copyout of
  the new file descriptors fails.
- Add a test to the socketpair regression test for this edge case.
This commit is contained in:
jhb 2007-04-02 19:15:47 +00:00
parent 67ec796ffc
commit b9a3a5afc7
2 changed files with 40 additions and 2 deletions

View File

@ -664,7 +664,10 @@ socketpair(td, uap)
fp2->f_ops = &socketops;
fp2->f_type = DTYPE_SOCKET;
FILE_UNLOCK(fp2);
so1 = so2 = NULL;
error = copyout(sv, uap->rsv, 2 * sizeof (int));
if (error)
goto free4;
fdrop(fp1, td);
fdrop(fp2, td);
goto done2;
@ -675,9 +678,11 @@ socketpair(td, uap)
fdclose(fdp, fp1, sv[0], td);
fdrop(fp1, td);
free2:
(void)soclose(so2);
if (so2 != NULL)
(void)soclose(so2);
free1:
(void)soclose(so1);
if (so1 != NULL)
(void)soclose(so1);
done2:
NET_UNLOCK_GIANT();
return (error);

View File

@ -49,6 +49,7 @@
int
main(int argc, char *argv[])
{
int fd1, fd2, fd3;
int sv[2];
/*
@ -123,6 +124,38 @@ main(int argc, char *argv[])
fprintf(stderr, "FAIL\n");
}
/*
* Check for sequential fd allocation, and give up early if not.
*/
fd1 = dup(STDIN_FILENO);
fd2 = dup(STDIN_FILENO);
if (fd2 != fd1 + 1) {
fprintf(stderr, "Non-sequential fd allocation\n");
fprintf(stderr, "FAIL\n");
exit(-1);
}
/* Allocate a socketpair using a bad destination address. */
if (socketpair(PF_UNIX, SOCK_DGRAM, 0, NULL) == 0) {
fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): opened\n");
fprintf(stderr, "FAIL\n");
exit(-1);
}
if (errno != EFAULT) {
fprintf(stderr, "socketpair(PF_UNIX, SOCK_DGRAM, NULL): %s\n",
strerror(errno));
fprintf(stderr, "FAIL\n");
exit(-1);
}
/* Allocate a file descriptor and make sure it's fd2+1. */
fd3 = dup(STDIN_FILENO);
if (fd3 != fd2 + 1) {
fprintf(stderr, "socketpair(..., NULL) allocated descriptors\n");
fprintf(stderr, "FAIL\n");
exit(-1);
}
fprintf(stderr, "PASS\n");
exit(0);
}