[BUG 3/3] smb: client: seal mount policy can be dropped after SMB3.1.1 reconnect

"Birtwhistle, Daniel" <[email protected]> Sun, 19 Jul 2026 18:09:20 +0000
Newsgroups org.kernel.vger.linux-cifs
Message-ID <SN4PR22MB28886AB743AFFB419EFBA70EEEC42@SN4PR22MB2888.namprd22.prod.outlook.com>
Resending in plain text because the original copy was rejected by linux-cifs due to Outlook always wanting talk html; apologies for the duplicate to direct recipients...

Hello Steve, Paulo, and linux-cifs maintainers,

My name is Daniel Birtwhistle. In my role, I assess security properties of
software inherited by GE HealthCare products. I am writing personally as the
researcher and technical contact.

This is the third of three coordinated CIFS client reports. The first covers
SMB2/3 response-signature enforcement, and the second asks for classification
of server-provided symlink mount confinement. This message covers a separate
SMB3 reconnect invariant and can be fixed and classified independently.

Summary

An SMB3.1.1 tree mounted with the explicit client option "seal" can reconnect
to an otherwise authenticated endpoint that does not advertise encryption and
continue in plaintext. The client logs "Encryption is requested but not
supported", but reconnect TREE_CONNECT succeeds and later file I/O is no
longer encrypted.

Runtime confirmation

I reproduced this on Linux 6.18.12+kali-arm64 with Samba 4.23.6, SMB 3.1.1,
NTLMSSP, mandatory signing, and client options sign,seal. The first server
supported AES-128-GCM but did not itself mandate encryption, so the client's
seal option was the sole policy requirement.

I then terminated the entire server service cgroup, including its per-client
worker, and compared two replacements on a fresh TCP connection:

- An encryption-capable replacement reconnected successfully,
  smb3_encryption_required() remained 1, and all post-reconnect application
  traffic remained in encrypted transform frames.
- A replacement using the same test credential but omitting
  SMB2_ENCRYPTION_CAPABILITIES also reconnected successfully. The kernel logged
  the warning for both the data and IPC trees, smb3_encryption_required()
  changed to 0, both SMB2_tcon() calls returned 0, and a fixed canary was read
  through plaintext TREE_CONNECT, CREATE and READ messages.

The matched packet captures each contain 88 packets. In the downgrade cell,
the initial stream has 36 encrypted transform frames, while the replacement
stream has none and its successful READ response visibly contains the fixed
test canary. The capable control has ten encrypted transform frames on its
replacement stream.

Current source

I rechecked upstream commit
980ab36ae5972c83f683b939e50c469c4947229e from 2026-07-19. Re-negotiate
replaces the active server capability state. On reconnect, SMB2_tcon() logs
when the existing tree requested sealing but the new server lacks encryption,
without returning an error. smb3_encryption_required() then conditions the
tree's seal request on that new capability and returns false, permitting the
plaintext traffic observed above.

The log-only reconnect check appears to have been introduced by
ae6f8dd4d0c8 in 2016 and remains present at the current commit above, giving
an affected source range from that introduction through current mainline.

Scope and fix direction

The terminal downgrade replacement deliberately knew the test credential. It
isolates and directly proves the encryption-policy failure; it is not a claim
that an unauthenticated replacement completed this exact end-to-end chain.
Forged encrypted responses still fail AEAD authentication. The first companion
report separately addresses bad-signature response acceptance and may compound
with this behavior, but I am not representing the combined no-key sealed
takeover as runtime-proven.

The client invariant appears straightforward: an explicit must-seal policy
should survive re-negotiate, and reconnect should fail closed if the replacement
cannot satisfy it. It may also be prudent to reject plaintext responses while
an active tree or session is under client-required sealing, instead of deciding
only from the received header form.

I built and differentially tested a candidate that rejects TREE_CONNECT before
request construction when the retained client policy requires sealing but the
new server cannot encrypt. On maintained 7.1.3+deb14-arm64, the capable
replacement still completed its sealed reconnect and canary read. The
capability-clearing replacement authenticated and established TCP, but every
tree reconnect returned -EOPNOTSUPP and the plaintext canary was never returned.

I have the candidate patch, guarded matched harness, raw captures, transcripts,
function-return traces and a hash manifest. I have not posted or attached the
reproducer here, but can provide the minimum evidence directly and can test a
proposed fix.

Please let me know how you would like this classified and whether maintained
stable branches should receive the correction.

Requested credit, if useful: Daniel Birtwhistle



Best Regards,

Daniel Birtwhistle
Senior Director Product Security & Assessment