diff --git a/fs/smb/common/compress/compress.c b/fs/smb/common/compress/compress.c index a4123c8f1c0a..4e5164b6dc33 100644 --- a/fs/smb/common/compress/compress.c +++ b/fs/smb/common/compress/compress.c @@ -130,12 +130,18 @@ static int smb_decompress_chained(__le16 alg, bool allow_chained, len = le32_to_cpu(payload->Length); /* - * CHAINED marks only the first payload. Requiring NONE on every - * later payload rejects ambiguous or independently chained data. + * Conforming chains must set CHAINED on the first payload. + * Windows 11 clients leave uninitialized residual bits in + * Flags on subsequent payload headers. Only reject trailing + * payloads that attempt to initiate an invalid nested chain. */ - if ((first && flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED)) || - (!first && flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_NONE))) - return -EINVAL; + if (first) { + if (flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED)) + return -EINVAL; + } else { + if (flags == cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED)) + return -EINVAL; + } src += SMB2_COMPRESSION_PAYLOAD_BASE_LEN; remaining -= SMB2_COMPRESSION_PAYLOAD_BASE_LEN;