From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpbgsg2.qq.com (smtpbgsg2.qq.com [54.254.200.128]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8FEC3B52F4 for ; Wed, 29 Jul 2026 05:38:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.254.200.128 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785303529; cv=none; b=HP8gl70qPRFE0RokDXTuO4IKr/CZWhBDo7JMTgLn3Yjm/rscL1chMGpJbSXsXQb7LeIDVLFW3hnmyeZAGP3eBV1b4VgqRYS5Lah0xzuJXYFdWccDeZ/znRFCT9B5gNZgIEvIOvyfcOdIzk+i2KNZ+BxbFnlD+gdsLwqoYAYXTcU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785303529; c=relaxed/simple; bh=N1/bu2gbYk2PTh+01Nh9LRLQizoERJC43r981joqOq0=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=WaParOD5r1JCzxtC89spPOx7E563zNxDqPG8W9m9vcIFpHq40r25cg64lr9S1Vz8qRRVr2PW41ytMDvwsaO27bCruJvqdZJkcN8k9Goio5kgXoXlCUSTUwiUnuDB9ZebM/Qz1L6lLN2plvlRZYKy8R3ym9KHEtt1zIX7mp5DM3A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ugreen.com; spf=pass smtp.mailfrom=ugreen.com; dkim=pass (1024-bit key) header.d=ugreen.com header.i=@ugreen.com header.b=AT6AvoBf; arc=none smtp.client-ip=54.254.200.128 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ugreen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ugreen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ugreen.com header.i=@ugreen.com header.b="AT6AvoBf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ugreen.com; s=pkvm2402; t=1785303508; bh=BBQAv/ZzACDpSHuQjeke8uzjlU3mEHl+neRNSNWMQ1g=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=AT6AvoBfBRHtXuLqvDk/AaN/C5tPzFuLkJNlfhZJOsmazRRlYZsyLgIEYJMNIBO1W ZnPLSVJiY3eZfw95peKC1WVAnHsqNvvaGiUyJRE93+32oVIXI1s8GrlDHnKLnmSr2+ dOb3Gdisbb3qDOMhrDCAVV0Fsp3mrGyYC0mcIjEs= X-QQ-mid: zesmtpsz9t1785303506t8e81de5d X-QQ-Originating-IP: QhtVy0fdCH9JSosScZug+MaMnL3g/GeOrGRccLdvFIQ= Received: from debian12.. ( [14.153.226.139]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 29 Jul 2026 13:38:20 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 7069893039906020633 EX-QQ-RecipientCnt: 4 From: Warren Xiong To: Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Warren Xiong Subject: [PATCH] tools/mm: prevent page_owner_sort from truncating input Date: Wed, 29 Jul 2026 13:38:12 +0800 Message-Id: <20260729053812.882137-1-warren.xiong@ugreen.com> X-Mailer: git-send-email 2.39.5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:ugreen.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: NjFgbzSnCN+Vl4wJMP11iyjkmBAl0knBQmnpKWDUCdiRLj+KRvB8ccg+ y4qeD5KaMpJ4Fv3RZyw9cxh13vhOa5J+QUNlqzExbmb9j1MWhJDMhx1CLRHnI0Ym8d43zfY mvY5BjTYDaBOcYC9wyOr5xL0qkLg5IN9fhrMhGlJn1f0f6CHbiLJFcLOPYWTQv79hGUA1Ac hmh8L1uIYI4umFP9zwXSFxx35CjFqWgG72YKM5TsfbQPLwr4hmSROKLz5oK9HPpetqTYWZa NDUUEKHodvyzDE0LZSgxWevbjfRyKtSaBOGohQOuMJFiYyuGsc+Kt8goQab3bH9ys+6hELK YO+ggduyBm+3MVyunSFcS1WyDPjDlFwR4X9ahdTjj+Z1ZNJ9b33KtaZ7jGvIcR2yaQDX7gD 3pBV8oLEwRx/JTeiiftiJ/hz614l1ghSZt7NqvWsYQEbP3ysakZbDk9Rs9TKCJtf0WSp91E xSEOT5H3nYO9HslMOo1OI2bFh+HT715A1axdRX8agAKDD6lCXSgDLs7g7qUbBkUaWy+B2pY Ncoe4iLAevavcfmXr4/7MyynADqmQ9liFh2qUYQGSzkN7ZTNFWrXSydSYDHYjWDrYDwfQVz tj5DcSs01KFLXlp9F8aG/6oiJq0TjxbZfTLjNkXqlS3aax4wyqJUxx2oKdPdfhGUivBzfaq MGXE7wKIJQ4YvI0SmBsJbdw0tSPos4UFrMOifLz44ct/fhS5bYt43S+VNo/VVXbXpVfmttB PCqeiC3CXP97/QCcqF5uA1xlR6a1ojUtY2IUUPBGpTGeZOaxO8MQehxiH4p1vIJbOZmwdSL WEeXKKPXXVrUBjBW6h8VCapTpo0IMlsGGSODf6IrxGFkZ87XkltvSaqOQ7Xs1QhoFzA9LB3 9HdhsYK9PEuE9c4ZvcCNZYZGPrZEbUQslz9vrCJ5ve6rPOVHSFWVwKUV5iHqty+ELvdnQ4B vdnCInP1tCS4Iwbh9o+yOB1MtxBa6TQPfs5n781gDlsNySg83RkwMl2zEtYaDYeV8Y6eHgw Uq7e/QJIFFpA32ZBKPmQv6SOBNz4RFU9MifuDLRX/XrdgHqiOMYQKdt2iy3tvsn/3AzLd3V g== X-QQ-XMRINFO: OD9hHCdaPRBwH5bRRRw8tsiH4UAatJqXfg== X-QQ-RECHKSPAM: 0 page_owner_sort opens the output file with "w" before reading the input. If both paths refer to the same file, this truncates the input and the tool silently processes zero records before returning success. Open the output without truncating it and compare the device and inode numbers of the opened files. Reject matching regular files, then truncate regular output files only after the check. This also detects hard link and symbolic link aliases while preserving non-regular outputs such as /dev/stdout. Signed-off-by: Warren Xiong --- tools/mm/page_owner_sort.c | 41 ++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/tools/mm/page_owner_sort.c b/tools/mm/page_owner_sort.c index 35d3d2549..602f541d8 100644 --- a/tools/mm/page_owner_sort.c +++ b/tools/mm/page_owner_sort.c @@ -713,7 +713,8 @@ int main(int argc, char **argv) FILE *fin, *fout; char *buf, *ext_buf; int i, count, compare_flag; - struct stat st; + int fout_fd; + struct stat st, output_st; int opt; struct option longopts[] = { { "pid", required_argument, NULL, 1 }, @@ -836,13 +837,46 @@ int main(int argc, char **argv) } fin = fopen(argv[optind], "r"); - fout = fopen(argv[optind + 1], "w"); - if (!fin || !fout) { + if (!fin) { usage(); perror("open: "); exit(1); } + if (fstat(fileno(fin), &st)) { + perror("fstat input"); + exit(1); + } + + /* + * Do not truncate the output until after checking whether it refers + * to the input file. Comparing the opened files also catches aliases + * created with hard links or symbolic links. + */ + fout_fd = open(argv[optind + 1], O_WRONLY | O_CREAT, 0666); + if (fout_fd < 0) { + perror("open output"); + exit(1); + } + if (fstat(fout_fd, &output_st)) { + perror("fstat output"); + exit(1); + } + if (S_ISREG(st.st_mode) && S_ISREG(output_st.st_mode) && + st.st_dev == output_st.st_dev && st.st_ino == output_st.st_ino) { + fprintf(stderr, "Input and output files must be different\n"); + exit(1); + } + if (S_ISREG(output_st.st_mode) && ftruncate(fout_fd, 0)) { + perror("truncate output"); + exit(1); + } + fout = fdopen(fout_fd, "w"); + if (!fout) { + perror("fdopen output"); + exit(1); + } + if (!check_regcomp(&order_pattern, "order\\s*([0-9]*),")) goto out_order; if (!check_regcomp(&pid_pattern, "pid\\s*([0-9]*),")) @@ -854,7 +888,6 @@ int main(int argc, char **argv) if (!check_regcomp(&ts_nsec_pattern, "ts\\s*([0-9]*)\\s*ns")) goto out_ts; - fstat(fileno(fin), &st); max_size = st.st_size / 100; /* hack ... */ list = malloc(max_size * sizeof(*list)); -- 2.39.5