From nobody Thu Sep 07 17:30:47 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RhR941nf0z4sJXJ; Thu, 7 Sep 2023 17:30:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RhR940tFJz4NmM; Thu, 7 Sep 2023 17:30:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694107848; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=yPzouVkHFc8CqJrPu2fWByXxQeD4tu+OCZdJ+P0Pkus=; b=BNmhw/jgeBG8yds8Sx+8d1ttUddyS1e0pC6fWkO4ZP1oxuVN7KpTxOeThUEcZCQJPnVDDW 6rjAQmIKQDV39O6zeWD/D5Aj4huqSODB6F9+xtFUq14MDA1wHw3oEbEAWDebQSUCQHMO9I X7j4hMmvgL/uZRfYIxhF0CzPcpUiac/Kw4FUT0XYENVuY6O2COZGH1RMZraSXY+NWxJoQm Up/MjtRQilqOSNq3z+EA9QumxYWsVVQjFNnCukNA+8Dfp+gOgLAWJHx69LDgkkTGli+Eoc V9tHdzZEIut0g5ajthTa1ZnmgnYKPawLWLBkKDscztkW3oAdpHPafAtq6HY9lg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1694107848; a=rsa-sha256; cv=none; b=wNzlgW8/ww/igPtsTzgNr2vLhwum/fO4uinvK2pLNJpQVynnlAoZJBxeyc7U/Qii13jxJy F+TGY1B3In7crttl9NNj0ubfbtpi7nsTLbDMXhDarTa6dvzXCmBRqPgRChN7wPxAmX0r0Y fnME/5ZhUhiMov/elWV04tcEiNw2eXSeMKsW2IYeaDW4ZSTtK8B33BpAZW6YM2aB9eslJM pqP5LlAYeWqL/e2vGqhN6Gy6Ams1fa5W5gEbF+fQaqbGICGkz2iPsh+FsbgmZTWSyXVHnY 9epT/YD4UNRXPBZtM5T4GR4cP7RBNqvcxOTQwLGf4LgVmPo2VmhniiVZoVyy1w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1694107848; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=yPzouVkHFc8CqJrPu2fWByXxQeD4tu+OCZdJ+P0Pkus=; b=ah3g3nXEkfXIVRt4usY/mc3oXmqWyNBFREU/NLkV4KH8omAddZdzquXCbVvQ+LcbFI0lPR M71kdXy0PKU2l7mGdc8QblJ2V44GAw4qNXP0sLghxOWWcJsYjbKW+Bj28I8thSBn6eod4I X8YaidR38vU1H8c4o3s/XcaixPDNwdJdIZeX1bb+eLYYJ+cN7k1z/P/C7NceFCQgb2eKwe N1kyJWjriSXMKGUoMd2KvjQUvj7jGGJtrjjYx5Nr2i4VcmhUutI5Paf4xpMqrKSEeqQ217 DsAxQxmSW7YTXY9C/SHIdO2zav5DWRB6GWIKD4EDjfmFufRfEmCN/Lr0tTrT/g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RhR936tspz17Q0; Thu, 7 Sep 2023 17:30:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 387HUlEs076728; Thu, 7 Sep 2023 17:30:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 387HUlqb076710; Thu, 7 Sep 2023 17:30:47 GMT (envelope-from git) Date: Thu, 7 Sep 2023 17:30:47 GMT Message-Id: <202309071730.387HUlqb076710@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 1fb1008822c6 - stable/13 - forkpty: Avoid fd leak if fork() fails. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 1fb1008822c64611535d3cb8f872b66a4e70acf1 Auto-Submitted: auto-generated The branch stable/13 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=1fb1008822c64611535d3cb8f872b66a4e70acf1 commit 1fb1008822c64611535d3cb8f872b66a4e70acf1 Author: Dag-Erling Smørgrav AuthorDate: 2023-08-17 13:48:42 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2023-09-07 17:26:58 +0000 forkpty: Avoid fd leak if fork() fails. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D41491 (cherry picked from commit a4aaee2120ce0a121f86e39e214c2fabe82f2762) --- lib/libutil/pty.c | 1 + lib/libutil/tests/Makefile | 1 + lib/libutil/tests/forkpty_test.c | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c index f52407608e9a..e5b42a666c7f 100644 --- a/lib/libutil/pty.c +++ b/lib/libutil/pty.c @@ -95,6 +95,7 @@ forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) return (-1); switch (pid = fork()) { case -1: + (void)close(master); (void)close(slave); return (-1); case 0: diff --git a/lib/libutil/tests/Makefile b/lib/libutil/tests/Makefile index dcbcb0ab4461..e096021fbb76 100644 --- a/lib/libutil/tests/Makefile +++ b/lib/libutil/tests/Makefile @@ -5,6 +5,7 @@ TAP_TESTS_C+= humanize_number_test TAP_TESTS_C+= pidfile_test TAP_TESTS_C+= trimdomain_test TAP_TESTS_C+= trimdomain-nodomain_test +ATF_TESTS_C+= forkpty_test WARNS?= 2 LIBADD+= util diff --git a/lib/libutil/tests/forkpty_test.c b/lib/libutil/tests/forkpty_test.c new file mode 100644 index 000000000000..3e54cf310150 --- /dev/null +++ b/lib/libutil/tests/forkpty_test.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2023 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +#include +#include +#include + +#include + +ATF_TC(forkfail); +ATF_TC_HEAD(forkfail, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check for fd leak when fork() fails"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(forkfail, tc) +{ + struct rlimit orl, nrl; + pid_t pid; + int prevfd, fd, pty; + + /* set process limit to 1 so fork() will fail */ + ATF_REQUIRE_EQ(0, getrlimit(RLIMIT_NPROC, &orl)); + nrl = orl; + nrl.rlim_cur = 1; + ATF_REQUIRE_EQ(0, setrlimit(RLIMIT_NPROC, &nrl)); + /* check first free fd */ + ATF_REQUIRE((fd = dup(0)) > 0); + ATF_REQUIRE_EQ(0, close(fd)); + /* attempt forkpty() */ + pid = forkpty(&pty, NULL, NULL, NULL); + if (pid == 0) { + /* child - fork() unexpectedly succeeded */ + _exit(0); + } + ATF_CHECK_ERRNO(EAGAIN, pid < 0); + if (pid > 0) { + /* parent - fork() unexpectedly succeeded */ + (void)waitpid(pid, NULL, 0); + } + /* check that first free fd hasn't changed */ + prevfd = fd; + ATF_REQUIRE((fd = dup(0)) > 0); + ATF_CHECK_EQ(prevfd, fd); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, forkfail); + return (atf_no_error()); +}