5 ksmbd server fixes, 4 for stable

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmGiaB4ACgkQiiy9cAdy
 T1H4PAv+OG94BZe+MyMdXgoRbOLiEeye7dm/TZnlpdtV96WmyrMkA4/1nyOc8k7F
 bNRn3ocuH3YCjjUB2kU6MZW5Kh9aSxULYgEC0zxuPcA9q4Ig4FehZD2U3r6fztFM
 U5Do9n1xRXjIgS/gI7DfZHSQ+SYVwBMAzRB3opplcs1CW68N7+WmKa5CQ6wH5vZM
 GqhU4+yFLhZGiXdxXTFF/bLKWer2PF9p5J4mLzRH0ugTG26tY7WnJcQIj+XrNTrN
 ccBSXr+9fHFFa9iGcLY08pghk8s1F6dXl/BLv7DFswKOoje7HsDLcWpNSVtVDojO
 0Fg5vVtuDKapCOrpmtPt8Khc4qgkxY6VpJyELMCwJuxrSzTE59C54gQcgJfZO97d
 bpGeV9L6D6VTLTe1LhUFCRQbc0FFO3daPWRrxrZnvtJeef70xVSZPtrQqNtpnAtM
 RwkN2Rf/Enl03w9U25nv3ymlKoHERiR2XZADLfWc5XdB40Lxc+fDccyoVP1wmxT8
 uicPpySr
 =bEt3
 -----END PGP SIGNATURE-----

Merge tag '5.16-rc2-ksmbd-fixes' of git://git.samba.org/ksmbd

Pull ksmbd fixes from Steve French:
 "Five ksmbd server fixes, four of them for stable:

   - memleak fix

   - fix for default data stream on filesystems that don't support xattr

   - error logging fix

   - session setup fix

   - minor doc cleanup"

* tag '5.16-rc2-ksmbd-fixes' of git://git.samba.org/ksmbd:
  ksmbd: fix memleak in get_file_stream_info()
  ksmbd: contain default data stream even if xattr is empty
  ksmbd: downgrade addition info error msg to debug in smb2_get_info_sec()
  docs: filesystem: cifs: ksmbd: Fix small layout issues
  ksmbd: Fix an error handling path in 'smb2_sess_setup()'
This commit is contained in:
Linus Torvalds 2021-11-27 14:49:35 -08:00
commit 3498e7f2bb
2 changed files with 22 additions and 18 deletions

View file

@ -157,7 +157,7 @@ Each layer
2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma) 2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma)
# sudo ksmbd.control -d "smb" # sudo ksmbd.control -d "smb"
3. Show what prints are enable. 3. Show what prints are enabled.
# cat /sys/class/ksmbd-control/debug # cat /sys/class/ksmbd-control/debug
[smb] auth vfs oplock ipc conn [rdma] [smb] auth vfs oplock ipc conn [rdma]

View file

@ -1697,8 +1697,10 @@ int smb2_sess_setup(struct ksmbd_work *work)
negblob_off = le16_to_cpu(req->SecurityBufferOffset); negblob_off = le16_to_cpu(req->SecurityBufferOffset);
negblob_len = le16_to_cpu(req->SecurityBufferLength); negblob_len = le16_to_cpu(req->SecurityBufferLength);
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) || if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
return -EINVAL; rc = -EINVAL;
goto out_err;
}
negblob = (struct negotiate_message *)((char *)&req->hdr.ProtocolId + negblob = (struct negotiate_message *)((char *)&req->hdr.ProtocolId +
negblob_off); negblob_off);
@ -4457,6 +4459,12 @@ static void get_file_stream_info(struct ksmbd_work *work,
&stat); &stat);
file_info = (struct smb2_file_stream_info *)rsp->Buffer; file_info = (struct smb2_file_stream_info *)rsp->Buffer;
buf_free_len =
smb2_calc_max_out_buf_len(work, 8,
le32_to_cpu(req->OutputBufferLength));
if (buf_free_len < 0)
goto out;
xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
if (xattr_list_len < 0) { if (xattr_list_len < 0) {
goto out; goto out;
@ -4465,12 +4473,6 @@ static void get_file_stream_info(struct ksmbd_work *work,
goto out; goto out;
} }
buf_free_len =
smb2_calc_max_out_buf_len(work, 8,
le32_to_cpu(req->OutputBufferLength));
if (buf_free_len < 0)
goto out;
while (idx < xattr_list_len) { while (idx < xattr_list_len) {
stream_name = xattr_list + idx; stream_name = xattr_list + idx;
streamlen = strlen(stream_name); streamlen = strlen(stream_name);
@ -4496,8 +4498,10 @@ static void get_file_stream_info(struct ksmbd_work *work,
":%s", &stream_name[XATTR_NAME_STREAM_LEN]); ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
next = sizeof(struct smb2_file_stream_info) + streamlen * 2; next = sizeof(struct smb2_file_stream_info) + streamlen * 2;
if (next > buf_free_len) if (next > buf_free_len) {
kfree(stream_buf);
break; break;
}
file_info = (struct smb2_file_stream_info *)&rsp->Buffer[nbytes]; file_info = (struct smb2_file_stream_info *)&rsp->Buffer[nbytes];
streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName, streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
@ -4514,6 +4518,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
file_info->NextEntryOffset = cpu_to_le32(next); file_info->NextEntryOffset = cpu_to_le32(next);
} }
out:
if (!S_ISDIR(stat.mode) && if (!S_ISDIR(stat.mode) &&
buf_free_len >= sizeof(struct smb2_file_stream_info) + 7 * 2) { buf_free_len >= sizeof(struct smb2_file_stream_info) + 7 * 2) {
file_info = (struct smb2_file_stream_info *) file_info = (struct smb2_file_stream_info *)
@ -4522,14 +4527,13 @@ static void get_file_stream_info(struct ksmbd_work *work,
"::$DATA", 7, conn->local_nls, 0); "::$DATA", 7, conn->local_nls, 0);
streamlen *= 2; streamlen *= 2;
file_info->StreamNameLength = cpu_to_le32(streamlen); file_info->StreamNameLength = cpu_to_le32(streamlen);
file_info->StreamSize = 0; file_info->StreamSize = cpu_to_le64(stat.size);
file_info->StreamAllocationSize = 0; file_info->StreamAllocationSize = cpu_to_le64(stat.blocks << 9);
nbytes += sizeof(struct smb2_file_stream_info) + streamlen; nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
} }
/* last entry offset should be 0 */ /* last entry offset should be 0 */
file_info->NextEntryOffset = 0; file_info->NextEntryOffset = 0;
out:
kvfree(xattr_list); kvfree(xattr_list);
rsp->OutputBufferLength = cpu_to_le32(nbytes); rsp->OutputBufferLength = cpu_to_le32(nbytes);
@ -5068,7 +5072,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
PROTECTED_DACL_SECINFO | PROTECTED_DACL_SECINFO |
UNPROTECTED_DACL_SECINFO)) { UNPROTECTED_DACL_SECINFO)) {
pr_err("Unsupported addition info: 0x%x)\n", ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
addition_info); addition_info);
pntsd->revision = cpu_to_le16(1); pntsd->revision = cpu_to_le16(1);