diff options
Diffstat (limited to 'fs/smb/client/smb2pdu.c')
| -rw-r--r-- | fs/smb/client/smb2pdu.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 23801b028530..afd823c9cbca 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -589,12 +589,17 @@ build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt) pneg_ctxt->DataLength = cpu_to_le16(sizeof(struct smb2_compression_capabilities_context) - sizeof(struct smb2_neg_context)); - pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(1); + + /* This enables the usage of the Pattern_V1 algorithm */ + pneg_ctxt->Flags = SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED; + pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(2); + /* - * Send the only algorithm we support (XXX: add others as they're + * Send the algorithms we support (XXX: add others as they're * implemented). */ pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77; + pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_PATTERN; } static unsigned int @@ -782,9 +787,13 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, struct smb2_compression_capabilities_context *ctxt) { unsigned int len = le16_to_cpu(ctxt->DataLength); - __le16 alg; + __le16 count, i; + int chained; server->compression.enabled = false; + server->compression.chained = false; + count = ctxt->CompressionAlgorithmCount; + chained = !!(ctxt->Flags & SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED); /* * Caller checked that DataLength remains within SMB boundary. We still @@ -796,18 +805,27 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, return; } - if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) { - pr_warn_once("invalid SMB3 compress algorithm count\n"); + if (unlikely(count != 2)) { + pr_warn_once("invalid SMB3 compress algorithm count '%u'\n", count); return; } - alg = ctxt->CompressionAlgorithms[0]; - if (!smb_compress_alg_valid(alg, false)) { - pr_warn_once("invalid compression algorithm '%u'\n", alg); - return; + for (i = 0; i < count; i++) { + __le16 alg = ctxt->CompressionAlgorithms[i]; + + if (!smb_compress_alg_valid(alg, false)) { + pr_warn_once("invalid compression algorithm '%u'\n", alg); + return; + } + + if (alg == SMB3_COMPRESS_PATTERN) { + if (chained) + server->compression.chained = true; + } else { + server->compression.alg = alg; + } } - server->compression.alg = alg; server->compression.enabled = true; } |
