diff options
| -rw-r--r-- | fs/cifs/cifs_debug.c | 6 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 46 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 15 |
4 files changed, 61 insertions, 7 deletions
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 5ff0b3d4c484..6a69f11aacf7 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
| @@ -332,6 +332,12 @@ skip_rdma: | |||
| 332 | #endif | 332 | #endif |
| 333 | seq_printf(m, "\nNumber of credits: %d Dialect 0x%x", | 333 | seq_printf(m, "\nNumber of credits: %d Dialect 0x%x", |
| 334 | server->credits, server->dialect); | 334 | server->credits, server->dialect); |
| 335 | if (server->compress_algorithm == SMB3_COMPRESS_LZNT1) | ||
| 336 | seq_printf(m, " COMPRESS_LZNT1"); | ||
| 337 | else if (server->compress_algorithm == SMB3_COMPRESS_LZ77) | ||
| 338 | seq_printf(m, " COMPRESS_LZ77"); | ||
| 339 | else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF) | ||
| 340 | seq_printf(m, " COMPRESS_LZ77_HUFF"); | ||
| 335 | if (server->sign) | 341 | if (server->sign) |
| 336 | seq_printf(m, " signed"); | 342 | seq_printf(m, " signed"); |
| 337 | if (server->posix_ext_supported) | 343 | if (server->posix_ext_supported) |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c22ab330238c..561f1395eddd 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -734,6 +734,7 @@ struct TCP_Server_Info { | |||
| 734 | #endif /* STATS2 */ | 734 | #endif /* STATS2 */ |
| 735 | unsigned int max_read; | 735 | unsigned int max_read; |
| 736 | unsigned int max_write; | 736 | unsigned int max_write; |
| 737 | __le16 compress_algorithm; | ||
| 737 | __le16 cipher_type; | 738 | __le16 cipher_type; |
| 738 | /* save initital negprot hash */ | 739 | /* save initital negprot hash */ |
| 739 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; | 740 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 035a568b3dbd..29f011d8d8e2 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -473,6 +473,19 @@ build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt) | |||
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | static void | 475 | static void |
| 476 | build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt) | ||
| 477 | { | ||
| 478 | pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES; | ||
| 479 | pneg_ctxt->DataLength = | ||
| 480 | cpu_to_le16(sizeof(struct smb2_compression_capabilities_context) | ||
| 481 | - sizeof(struct smb2_neg_context)); | ||
| 482 | pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(3); | ||
| 483 | pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77; | ||
| 484 | pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_LZ77_HUFF; | ||
| 485 | pneg_ctxt->CompressionAlgorithms[2] = SMB3_COMPRESS_LZNT1; | ||
| 486 | } | ||
| 487 | |||
| 488 | static void | ||
| 476 | build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt) | 489 | build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt) |
| 477 | { | 490 | { |
| 478 | pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; | 491 | pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; |
| @@ -538,10 +551,17 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, | |||
| 538 | *total_len += ctxt_len; | 551 | *total_len += ctxt_len; |
| 539 | pneg_ctxt += ctxt_len; | 552 | pneg_ctxt += ctxt_len; |
| 540 | 553 | ||
| 554 | build_compression_ctxt((struct smb2_compression_capabilities_context *) | ||
| 555 | pneg_ctxt); | ||
| 556 | ctxt_len = DIV_ROUND_UP( | ||
| 557 | sizeof(struct smb2_compression_capabilities_context), 8) * 8; | ||
| 558 | *total_len += ctxt_len; | ||
| 559 | pneg_ctxt += ctxt_len; | ||
| 560 | |||
| 541 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); | 561 | build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); |
| 542 | *total_len += sizeof(struct smb2_posix_neg_context); | 562 | *total_len += sizeof(struct smb2_posix_neg_context); |
| 543 | 563 | ||
| 544 | req->NegotiateContextCount = cpu_to_le16(3); | 564 | req->NegotiateContextCount = cpu_to_le16(4); |
| 545 | } | 565 | } |
| 546 | 566 | ||
| 547 | static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) | 567 | static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) |
| @@ -559,6 +579,27 @@ static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) | |||
| 559 | printk_once(KERN_WARNING "unknown SMB3 hash algorithm\n"); | 579 | printk_once(KERN_WARNING "unknown SMB3 hash algorithm\n"); |
| 560 | } | 580 | } |
| 561 | 581 | ||
| 582 | static void decode_compress_ctx(struct TCP_Server_Info *server, | ||
| 583 | struct smb2_compression_capabilities_context *ctxt) | ||
| 584 | { | ||
| 585 | unsigned int len = le16_to_cpu(ctxt->DataLength); | ||
| 586 | |||
| 587 | /* sizeof compress context is a one element compression capbility struct */ | ||
| 588 | if (len < 10) { | ||
| 589 | printk_once(KERN_WARNING "server sent bad compression cntxt\n"); | ||
| 590 | return; | ||
| 591 | } | ||
| 592 | if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) { | ||
| 593 | printk_once(KERN_WARNING "illegal SMB3 compress algorithm count\n"); | ||
| 594 | return; | ||
| 595 | } | ||
| 596 | if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) { | ||
| 597 | printk_once(KERN_WARNING "unknown compression algorithm\n"); | ||
| 598 | return; | ||
| 599 | } | ||
| 600 | server->compress_algorithm = ctxt->CompressionAlgorithms[0]; | ||
| 601 | } | ||
| 602 | |||
| 562 | static int decode_encrypt_ctx(struct TCP_Server_Info *server, | 603 | static int decode_encrypt_ctx(struct TCP_Server_Info *server, |
| 563 | struct smb2_encryption_neg_context *ctxt) | 604 | struct smb2_encryption_neg_context *ctxt) |
| 564 | { | 605 | { |
| @@ -623,6 +664,9 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, | |||
| 623 | else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) | 664 | else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) |
| 624 | rc = decode_encrypt_ctx(server, | 665 | rc = decode_encrypt_ctx(server, |
| 625 | (struct smb2_encryption_neg_context *)pctx); | 666 | (struct smb2_encryption_neg_context *)pctx); |
| 667 | else if (pctx->ContextType == SMB2_COMPRESSION_CAPABILITIES) | ||
| 668 | decode_compress_ctx(server, | ||
| 669 | (struct smb2_compression_capabilities_context *)pctx); | ||
| 626 | else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) | 670 | else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) |
| 627 | server->posix_ext_supported = true; | 671 | server->posix_ext_supported = true; |
| 628 | else | 672 | else |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 93dd3b431585..c7d5813bebd8 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
| @@ -297,16 +297,19 @@ struct smb2_encryption_neg_context { | |||
| 297 | } __packed; | 297 | } __packed; |
| 298 | 298 | ||
| 299 | /* See MS-SMB2 2.2.3.1.3 */ | 299 | /* See MS-SMB2 2.2.3.1.3 */ |
| 300 | #define SMB3_COMPRESS_NONE 0x0000 | 300 | #define SMB3_COMPRESS_NONE cpu_to_le16(0x0000) |
| 301 | #define SMB3_COMPRESS_LZNT1 0x0001 | 301 | #define SMB3_COMPRESS_LZNT1 cpu_to_le16(0x0001) |
| 302 | #define SMB3_COMPRESS_LZ77 0x0002 | 302 | #define SMB3_COMPRESS_LZ77 cpu_to_le16(0x0002) |
| 303 | #define SMB3_COMPRESS_LZ77_HUFF 0x0003 | 303 | #define SMB3_COMPRESS_LZ77_HUFF cpu_to_le16(0x0003) |
| 304 | 304 | ||
| 305 | struct smb2_compression_capabilities_context { | 305 | struct smb2_compression_capabilities_context { |
| 306 | __le16 ContextType; /* 3 */ | ||
| 307 | __le16 DataLength; | ||
| 308 | __u32 Reserved; | ||
| 306 | __le16 CompressionAlgorithmCount; | 309 | __le16 CompressionAlgorithmCount; |
| 307 | __u16 Padding; | 310 | __u16 Padding; |
| 308 | __u32 Reserved; | 311 | __u32 Reserved1; |
| 309 | __u16 CompressionAlgorithms[1]; | 312 | __le16 CompressionAlgorithms[3]; |
| 310 | } __packed; | 313 | } __packed; |
| 311 | 314 | ||
| 312 | /* | 315 | /* |
