From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 506A741228D for ; Wed, 1 Jul 2026 22:07:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782943663; cv=none; b=GHnxV9tdUvBdw+E8cwnnvqu7itMiMozn0PCr6JD3aOEBKHJ497AyJh2PpLsrSfXTCaD/uai8oSNoWnCJ69odgCukrKTY5xEpxpxAZDe3EQdleluCvC9i+eMG2J+maYQWO8k1pkXDfsGEYzPLE+FMiSSNeVP3UItwHsYVm9KUuvU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782943663; c=relaxed/simple; bh=AJcvxrjgFC/vzLLX5SpDA1f1GuEyqQdgHyLo32ybmW4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=mgjbUnCmhGUESScnKqIpQLwopXdohGNcEmCTz3GvVyqYRd0KIHnZztY1MNMX1YPMhHhOm/jq59hyf8n68dDM6DZf477TqyeqqjLu3R8aA98uJUEj8xRGAltoa0p/5amnJo1PbnWlgL5QwnOViz75Lkd5uEVhvmbXUA4KadC9wGQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=oy1pjo9Y; arc=none smtp.client-ip=209.85.210.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oy1pjo9Y" Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-8478cc93299so761748b3a.2 for ; Wed, 01 Jul 2026 15:07:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782943653; x=1783548453; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=AtXiHxBOWtzv91/tPtTE+82KTENG8TullCuPYV97qQ4=; b=oy1pjo9Yz62Jn34veTzC9iLJh7KjxLi0B2IfkUPCLVI9NAuMEnoy8FkWYonY9U3iJl RXj4lstajnBwivDkeu+t/T6LjyqLFCt9U8euvXLo0PHwhKX0smtEzIJK6VoPshsrzDtH QSPL5kbi5PHH3ouE+4Ni+KJQ95qliMV0zuEL/0AAiSYV9bNQBgq4McLqnGVAMJCdltDE 5+RfXfjA2GWMy+Hw+6CDJeMhof1fDRpuCKCfS9Di3nGXJSDoR6XB1CBdJREOu1E16PQ3 wzqdOHUm7AelNC0+q5KskTKC1icM/qKZXNedfujqZ6yC1XPQwzE5YV6OIESlYdX471wr 1Xfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782943653; x=1783548453; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=AtXiHxBOWtzv91/tPtTE+82KTENG8TullCuPYV97qQ4=; b=r7fbFFiEfpyDJdEUb4i2Jv3MdTAxGRc2l7yO7mUwKzzGhdFwJOmY6HEWbPMXNdEdpL 2/iOecwLPwmAkLSG6fbGN6GJ9YNhbYkiZbDli0v/H8pAE+Ud72/RZ60CBSeWKARSAauu 5NkG8xwpXdcQ09b7S4irwwWmkAYyzwJ/chbrzNjRHa04YOtOm1HQuPTmpsLV4sMpt4hQ oj6uBtdGpO7wG84t7QdFTMHkytYdHklAqrBNNHd7PoVAQg1yp6hgjrkkOc7f3rmSuwVp SrJ0rQGBiRccLTc4WsDgXl8rlmLISHZPmm9Rnhc+WWCn1/Jlmr2xbgTWdUu+qVqTpeAj iAnw== X-Gm-Message-State: AOJu0Yz0RXNU2gbkW1S5VgggDQKh/yekQWUwdGpii/v+W4ngc234VGj1 puiyAjMLnf9ScV9dsoUV2n01peMYudTlF7r74mR2w1hAI6GWzyHDDothX3NzWhmG X-Gm-Gg: AfdE7clsY2dXRiJFMwSWv+wtmUiSYcPC3Z5KNaaeHpkQSm9gFXQDCEwMVrqkCXpCWnB /rsux2Do7FCnbQxsM7WQj+5IxlUpCataJ9zNCJsL6ERQuJvVwgVvdtMU6KiEghRLAN+CyWyGLnz riSY/BzmCwUwCn6rlnpPV1/5RkQGjJ4VciYiO/OFTaXJE/QPV6Xokv4mjuLLHCs2lXSuuxMMTFA j+N41oBBG0viZyn3Vl92piqfRKsStKY5bWZnLv0d8arlDe7RlFey6B4dp7tc/O4xw8WecUQmjRk S6YmT+cv07/8G0pt+gieIZgTdblmmERPaUemE6dwIfnQ0FySIuqUzfwXi28yQJbQMGNw58u/Fj8 frn1wxKov+JxKoJUjeChmQ1QLOdoWf5NQyWoxezAa1G8qUk7ddhmoJmwSLBsbVhPIwDhuFLeW3N tJF5x1DWaP0pEt3NXz+cdUBdA9YCa/JwjvqlOMuKqFvElV2yPFfN1l5pRVkKOO/bg= X-Received: by 2002:a05:6a00:4ac7:b0:847:9e62:251 with SMTP id d2e1a72fcca58-847c09ca681mr3305708b3a.54.1782943652943; Wed, 01 Jul 2026 15:07:32 -0700 (PDT) Received: from DESKTOP-L3Q0GIV.localdomain ([203.230.195.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-847cb78d69csm390395b3a.25.2026.07.01.15.07.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Jul 2026 15:07:32 -0700 (PDT) From: =?UTF-8?q?=EC=9D=B4=EC=83=81=ED=98=B8?= To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?=EC=9D=B4=EC=83=81=ED=98=B8?= , linux-fsdevel@vger.kernel.org Subject: [PATCH] romfs: detect hard link cycles Date: Thu, 2 Jul 2026 07:07:29 +0900 Message-ID: <20260701220729.822112-1-kudo3228@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit romfs_iget() follows on-disk hard link entries until it reaches a non-hard link inode: pos = be32_to_cpu(ri.spec) & ROMFH_MASK; The target position is image-controlled, and the loop does not detect cycles. A crafted romfs image can make the root inode a hard link. The hard link can point back to itself and leave mount(2) spinning in the kernel. Reject excessive hard link indirection with -ELOOP. Normal romfs images do not need long hard link chains. This bounds corrupted-image traversal. Propagate romfs_iget() errors from lookup because hard link traversal can now fail with -ELOOP. Signed-off-by: 이상호 --- fs/romfs/super.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 794a6051d0b5..2d42f7f95260 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -240,6 +240,8 @@ static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry, if ((be32_to_cpu(ri.next) & ROMFH_TYPE) == ROMFH_HRD) offset = be32_to_cpu(ri.spec) & ROMFH_MASK; inode = romfs_iget(dir->i_sb, offset); + if (IS_ERR(inode)) + return ERR_CAST(inode); break; } @@ -262,6 +262,8 @@ static const struct inode_operations romfs_dir_inode_operations = { .lookup = romfs_lookup, }; +#define ROMFS_MAX_HARDLINK_DEPTH 64 + /* * get a romfs inode based on its position in the image (which doubles as the * inode number) @@ -274,6 +276,7 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos) struct inode *i; unsigned long nlen; unsigned nextfh; + unsigned int depth = 0; int ret; umode_t mode; @@ -289,6 +292,9 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos) if ((nextfh & ROMFH_TYPE) != ROMFH_HRD) break; + if (++depth > ROMFS_MAX_HARDLINK_DEPTH) + return ERR_PTR(-ELOOP); + pos = be32_to_cpu(ri.spec) & ROMFH_MASK; } -- 2.43.0