check_windows_hibernation_status() calls ntfs_lookup_inode_by_name() which returns MFT references read directly from disk (untrusted data). The current code extracts error codes via MREF_ERR() without proper validation, allowing maliciously crafted NTFS images to trigger incorrect error handling. The MFT reference encoding uses bit 47 as an error indicator, but the lower 32 bits can contain arbitrary values. If a malicious image sets the error bit with a positive integer (e.g., 1), MREF_ERR() returns that positive value. This can cause the function to incorrectly interpret the error as "Windows is hibernated" status, potentially leading to the filesystem being mounted read-only (denial of service). Fix by strictly validating error codes: only accept negative values in the valid errno range [-MAX_ERRNO, -1]. Convert all other values (positive, zero, or out-of-range) to -EIO to indicate disk corruption. This prevents potential security issues and ensures proper error handling for corrupted or malicious NTFS filesystems. Fixes: 1e9ea7e04472d ("Revert \"fs: Remove NTFS classic\"") Cc: stable@vger.kernel.org Signed-off-by: Hongling Zeng --- fs/ntfs/super.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 8abe7bee4c0d..78f7e9fa76a0 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -1168,9 +1168,16 @@ static int check_windows_hibernation_status(struct ntfs_volume *vol) ntfs_debug("hiberfil.sys not present. Windows is not hibernated on the volume."); return 0; } - /* A real error occurred. */ - ntfs_error(vol->sb, "Failed to find inode number for hiberfil.sys."); - return ret; + /* Validate error code from untrusted disk data. */ + if (ret < 0 && ret >= -MAX_ERRNO) { + ntfs_error(vol->sb, "Failed to find inode number for hiberfil.sys."); + return ret; + } + /* Invalid error code indicates disk corruption. */ + ntfs_error(vol->sb, + "hiberfil.sys lookup returned invalid error code %i, treating as disk corruption.", + ret); + return -EIO; } /* Get the inode. */ vi = ntfs_iget(vol->sb, MREF(mref)); -- 2.25.1