Merge tag '6.7-rc-smb3-server-part2' of git://git.samba.org/ksmbd
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Nov 2023 18:23:53 +0000 (10:23 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Nov 2023 18:23:53 +0000 (10:23 -0800)
Pull smb server fixes from Steve French:

 - slab out of bounds fix in ACL handling

 - fix malformed request oops

 - minor doc fix

* tag '6.7-rc-smb3-server-part2' of git://git.samba.org/ksmbd:
  ksmbd: handle malformed smb1 message
  ksmbd: fix kernel-doc comment of ksmbd_vfs_kern_path_locked()
  ksmbd: fix slab out of bounds write in smb_inherit_dacl()

fs/smb/server/smb_common.c
fs/smb/server/smbacl.c
fs/smb/server/vfs.c

index e6ba1e9b8589aaa456963f898946573a5491d460..6691ae68af0c09b1c27c0c4ff58269e57182c873 100644 (file)
@@ -366,11 +366,22 @@ static int smb1_allocate_rsp_buf(struct ksmbd_work *work)
        return 0;
 }
 
+/**
+ * set_smb1_rsp_status() - set error type in smb response header
+ * @work:      smb work containing smb response header
+ * @err:       error code to set in response
+ */
+static void set_smb1_rsp_status(struct ksmbd_work *work, __le32 err)
+{
+       work->send_no_response = 1;
+}
+
 static struct smb_version_ops smb1_server_ops = {
        .get_cmd_val = get_smb1_cmd_val,
        .init_rsp_hdr = init_smb1_rsp_hdr,
        .allocate_rsp_buf = smb1_allocate_rsp_buf,
        .check_user_session = smb1_check_user_session,
+       .set_rsp_status = set_smb1_rsp_status,
 };
 
 static int smb1_negotiate(struct ksmbd_work *work)
index 6c0305be895e56fb11464c5fe17245afc4354447..51b8bfab74813fb3f79bc85e2155eeebd84f2d79 100644 (file)
@@ -1107,6 +1107,7 @@ pass:
                struct smb_acl *pdacl;
                struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
                int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
+               int pntsd_alloc_size;
 
                if (parent_pntsd->osidoffset) {
                        powner_sid = (struct smb_sid *)((char *)parent_pntsd +
@@ -1119,9 +1120,10 @@ pass:
                        pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
                }
 
-               pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size +
-                               pgroup_sid_size + sizeof(struct smb_acl) +
-                               nt_size, GFP_KERNEL);
+               pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size +
+                       pgroup_sid_size + sizeof(struct smb_acl) + nt_size;
+
+               pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL);
                if (!pntsd) {
                        rc = -ENOMEM;
                        goto free_aces_base;
@@ -1136,6 +1138,27 @@ pass:
                pntsd->gsidoffset = parent_pntsd->gsidoffset;
                pntsd->dacloffset = parent_pntsd->dacloffset;
 
+               if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size >
+                   pntsd_alloc_size) {
+                       rc = -EINVAL;
+                       kfree(pntsd);
+                       goto free_aces_base;
+               }
+
+               if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size >
+                   pntsd_alloc_size) {
+                       rc = -EINVAL;
+                       kfree(pntsd);
+                       goto free_aces_base;
+               }
+
+               if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size >
+                   pntsd_alloc_size) {
+                       rc = -EINVAL;
+                       kfree(pntsd);
+                       goto free_aces_base;
+               }
+
                if (pntsd->osidoffset) {
                        struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd +
                                        le32_to_cpu(pntsd->osidoffset));
index 1053127f71adfbaa946809da2f84a41ffd065564..c53dea5598fc63718e5df7f42e2079d5ac00497a 100644 (file)
@@ -1177,9 +1177,10 @@ static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name,
 
 /**
  * ksmbd_vfs_kern_path_locked() - lookup a file and get path info
- * @name:      file path that is relative to share
- * @flags:     lookup flags
- * @path:      if lookup succeed, return path info
+ * @name:              file path that is relative to share
+ * @flags:             lookup flags
+ * @parent_path:       if lookup succeed, return parent_path info
+ * @path:              if lookup succeed, return path info
  * @caseless:  caseless filename lookup
  *
  * Return:     0 on success, otherwise error