smb: wsize blocks of bytes followed with binary zeros on copy, destroying data
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
linux (Ubuntu) | Status tracked in Noble | |||||
Mantic |
Fix Released
|
High
|
Matthew Ruffell | |||
Noble |
Fix Released
|
High
|
Matthew Ruffell |
Bug Description
BugLink: https:/
[Impact]
Upon installing the 6.5 HWE kernel on Jammy, users with a custom wsize set will see data destruction when copying files from their systems onto a cifs smb mount.
wsize defaults to 65535 bytes, but when set to smaller values, like 16850, users will see blocks of 16850 bytes copied over, followed by 3900 binary zeros, followed by the next block of data followed by more binary zeros. This destroys what you are copying, and the data corruption is completely silent.
A workaround is to set wsize to a multiple of PAGE_SIZE.
[Fix]
This was fixed upstream in 6.8-rc5 by the following:
commit 4860abb91f3d7fb
Author: Steve French <email address hidden>
Date: Tue Feb 6 16:34:22 2024 -0600
Subject: smb: Fix regression in writes when non-standard maximum write size negotiated
Link: https:/
This patch has been selected for upstream stable.
The patch looks at wsize negotiation from the server, and also what is set on the mount command line, and if not a multiple of PAGE_SIZE, rounds it down, taking care to not be 0.
The real corruption bug still exists in netfs/folios subsystems and we are looking for it still, but this solves the immediate data corruption issues on smb.
[Testcase]
Start two VMs, one for the server, and the other, the client.
Server
------
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install samba
$ sudo vim /etc/samba/smb.conf
server min protocol = NT1
[sambashare]
comment = Samba on Ubuntu
path = /home/ubuntu/
read only = no
browsable = yes
$ mkdir ~/sambashare
$ sudo smbpasswd -a ubuntu
Client
------
$ sudo apt update
$ sudo apt install cifs-utils
$ mkdir ~/share
$ sudo mount -t cifs -o username=
$ ( set -o pipefail && head --bytes=$(( 55 * 1000 )) /dev/zero | openssl enc -aes-128-ctr -nosalt -pass "pass:my-seed" -iter 1 | hexdump --no-squeezing --format '40/1 "%02x"' --format '"\n"' >"testdata.txt" )
$ sha256sum testdata.txt
9ec09af020dce32
Now copy the file to the share.
Client
------
$ cp testdata.txt share/
Server
------
$ sha256sum sambashare/
9e573a0aa795f9c
The SHA256 hash is different. If you view the file with less, you will find a block of wsize=16850 bytes, then 3900 bytes of binary zeros, followed by another wsize=16850 bytes, then 3900 bytes of binary zeros, etc.
An example of a broken file is:
https:/
[Where problems could occur]
We are changing the wsize that the SMB server negotiates or the user explicitly sets on the mount command line to a safe value, if the asked for value was not a multiple of PAGE_SIZE.
It is unlikely that any users will notice any difference. If the wsize happens to be rounded down to a significantly smaller number, there may be a small performance impact, e.g. you set wsize=8094 for some reason, it would round down to wsize=4096, and lead to double the writes. At least you have data integrity though.
Most users default to wsize=65535, and will have no impact at all. Only those with very old smb 1.0 servers that negotiate down to 16850 will see any difference.
If a regression were to occur, it could result in user's wsize being incorrectly set, leading to the underlying netfs/folios data corruption being triggered and causing data corruption.
[Other info]
The issue was introduced in 6.3-rc1 by:
commit d08089f649a0cfb
Author: David Howells <email address hidden>
Date: Mon Jan 24 21:13:24 2022 +0000
Subject: cifs: Change the I/O paths to use an iterator rather than a page list
Link: https:/
Upstream mailing list discussion:
https://<email address hidden>
CVE References
summary: |
- smb1: wsize blocks of bytes followed with binary zeros on copy, + smb: wsize blocks of bytes followed with binary zeros on copy, destroying data |
description: | updated |
tags: | added: mantic noble |
Changed in linux (Ubuntu Mantic): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Noble): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Noble): | |
status: | Fix Committed → Fix Released |
Today I temporarily reverted back to Kernel 6.2.0-39-generic, by choosing it from the Grub bootloader, and the SMB 1.0 network shares started working correctly again. I think it is clear that Kernel 6.5 is broken in this respect.
Fortunately, package linux-image- 6.2.0-39- generic is still installed. Package linux-image- 5.15.0- 91-generic is also there.
I am worried that the 6.2 Kernel version will get kicked out on the next system update. I am guessing that the system will automatically keep the original 5.15 kernel series and the new 6.5, but not the 6.2 series.
In the past years, updating the system failed a couple of times because the /boot partition was full, which I guess it is some kind of Ubuntu shortcoming, as my installation was nothing out of the ordinary. I had to manually delete some kernel-related packages. These memories reminded me that the space for old kernels is limited, so that the 6.2 version may get automatically kicked out the next time around. And version 5.15 is too old, I wonder what kind of problems that might cause in my system.