mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
diff: Fix pagination leak
* Drop an unnecessary variable and rename pidfd to procd. * Rewinding stdout serves no purpose, so stop doing it. * Don't bother freeing memory or setting the global status right before erroring out. * Error out if dup(2) or dup2(2) fail. * In the unlikely case that our pipe is equal to stdout, we need to record that information so we don't close it when cleaning up. * Don't bother closing a descriptor before dup2(2)ing to it. * Don't forget to close the the process descriptor after reaping the child process. PR: 266592 MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: kevans, markj Differential Revision: https://reviews.freebsd.org/D55112
This commit is contained in:
1 parent
270492602b
commit
c3904a7de7
2 files changed
+11
-13
No files matched your search
+10
-12
@@ -45,7 +45,6 @@ struct pr *
|
||||
start_pr(char *file1, char *file2)
|
||||
{
|
||||
int pfd[2];
|
||||
int pr_pd;
|
||||
pid_t pid;
|
||||
char *header;
|
||||
struct pr *pr;
|
||||
@@ -55,13 +54,10 @@ start_pr(char *file1, char *file2)
|
||||
xasprintf(&header, "%s %s %s", diffargs, file1, file2);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
fflush(stdout);
|
||||
rewind(stdout);
|
||||
if (pipe(pfd) == -1)
|
||||
err(2, "pipe");
|
||||
switch ((pid = pdfork(&pr_pd, PD_CLOEXEC))) {
|
||||
switch ((pid = pdfork(&pr->procd, PD_CLOEXEC))) {
|
||||
case -1:
|
||||
status |= 2;
|
||||
free(header);
|
||||
err(2, "No more processes");
|
||||
case 0:
|
||||
/* child */
|
||||
@@ -73,15 +69,17 @@ start_pr(char *file1, char *file2)
|
||||
execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0);
|
||||
_exit(127);
|
||||
default:
|
||||
pr->pidfd = pr_pd;
|
||||
/* parent */
|
||||
if (pfd[1] != STDOUT_FILENO) {
|
||||
pr->ostdout = dup(STDOUT_FILENO);
|
||||
dup2(pfd[1], STDOUT_FILENO);
|
||||
if (pfd[1] == STDOUT_FILENO) {
|
||||
pr->ostdout = STDOUT_FILENO;
|
||||
} else {
|
||||
if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 ||
|
||||
dup2(pfd[1], STDOUT_FILENO) < 0) {
|
||||
err(2, "stdout");
|
||||
}
|
||||
close(pfd[1]);
|
||||
}
|
||||
close(pfd[0]);
|
||||
rewind(stdout);
|
||||
free(header);
|
||||
}
|
||||
return (pr);
|
||||
@@ -98,14 +96,14 @@ stop_pr(struct pr *pr)
|
||||
|
||||
fflush(stdout);
|
||||
if (pr->ostdout != STDOUT_FILENO) {
|
||||
close(STDOUT_FILENO);
|
||||
dup2(pr->ostdout, STDOUT_FILENO);
|
||||
close(pr->ostdout);
|
||||
}
|
||||
while (pdwait(pr->pidfd, &wstatus, WEXITED, NULL, NULL) == -1) {
|
||||
while (pdwait(pr->procd, &wstatus, WEXITED, NULL, NULL) == -1) {
|
||||
if (errno != EINTR)
|
||||
err(2, "pdwait");
|
||||
}
|
||||
close(pr->procd);
|
||||
free(pr);
|
||||
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
|
||||
errx(2, "pr exited abnormally");
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
|
||||
struct pr {
|
||||
int ostdout;
|
||||
int pidfd;
|
||||
int procd;
|
||||
};
|
||||
|
||||
struct pr *start_pr(char *file1, char *file2);
|
||||
|
||||
Reference in new issue
Block a user