Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'v7.0-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

- Fix potential use after free errors

- Fix refcount leak in smb2 open error path

- Prevent allowing logging signing or encryption keys

* tag 'v7.0-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: Don't log keys in SMB3 signing and encryption key generation
smb: server: fix use-after-free in smb2_open()
ksmbd: fix use-after-free in smb_lazy_parent_lease_break_close()
ksmbd: fix use-after-free by using call_rcu() for oplock_info
ksmbd: fix use-after-free in proc_show_files due to early rcu_read_unlock
smb/server: Fix another refcount leak in smb2_open()

+39 -41
+2 -20
fs/smb/server/auth.c
··· 589 589 if (!(conn->dialect >= SMB30_PROT_ID && signing->binding)) 590 590 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE); 591 591 592 - ksmbd_debug(AUTH, "dumping generated AES signing keys\n"); 592 + ksmbd_debug(AUTH, "generated SMB3 signing key\n"); 593 593 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); 594 - ksmbd_debug(AUTH, "Session Key %*ph\n", 595 - SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); 596 - ksmbd_debug(AUTH, "Signing Key %*ph\n", 597 - SMB3_SIGN_KEY_SIZE, key); 598 594 return 0; 599 595 } 600 596 ··· 648 652 ptwin->decryption.context, 649 653 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE); 650 654 651 - ksmbd_debug(AUTH, "dumping generated AES encryption keys\n"); 655 + ksmbd_debug(AUTH, "generated SMB3 encryption/decryption keys\n"); 652 656 ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type); 653 657 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); 654 - ksmbd_debug(AUTH, "Session Key %*ph\n", 655 - SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); 656 - if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || 657 - conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { 658 - ksmbd_debug(AUTH, "ServerIn Key %*ph\n", 659 - SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey); 660 - ksmbd_debug(AUTH, "ServerOut Key %*ph\n", 661 - SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey); 662 - } else { 663 - ksmbd_debug(AUTH, "ServerIn Key %*ph\n", 664 - SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey); 665 - ksmbd_debug(AUTH, "ServerOut Key %*ph\n", 666 - SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey); 667 - } 668 658 } 669 659 670 660 void ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
+25 -10
fs/smb/server/oplock.c
··· 120 120 kfree(lease); 121 121 } 122 122 123 - static void free_opinfo(struct oplock_info *opinfo) 123 + static void __free_opinfo(struct oplock_info *opinfo) 124 124 { 125 125 if (opinfo->is_lease) 126 126 free_lease(opinfo); 127 127 if (opinfo->conn && atomic_dec_and_test(&opinfo->conn->refcnt)) 128 128 kfree(opinfo->conn); 129 129 kfree(opinfo); 130 + } 131 + 132 + static void free_opinfo_rcu(struct rcu_head *rcu) 133 + { 134 + struct oplock_info *opinfo = container_of(rcu, struct oplock_info, rcu); 135 + 136 + __free_opinfo(opinfo); 137 + } 138 + 139 + static void free_opinfo(struct oplock_info *opinfo) 140 + { 141 + call_rcu(&opinfo->rcu, free_opinfo_rcu); 130 142 } 131 143 132 144 struct oplock_info *opinfo_get(struct ksmbd_file *fp) ··· 188 176 free_opinfo(opinfo); 189 177 } 190 178 191 - static void opinfo_add(struct oplock_info *opinfo) 179 + static void opinfo_add(struct oplock_info *opinfo, struct ksmbd_file *fp) 192 180 { 193 - struct ksmbd_inode *ci = opinfo->o_fp->f_ci; 181 + struct ksmbd_inode *ci = fp->f_ci; 194 182 195 183 down_write(&ci->m_lock); 196 184 list_add(&opinfo->op_entry, &ci->m_op_list); ··· 1135 1123 1136 1124 rcu_read_lock(); 1137 1125 opinfo = rcu_dereference(fp->f_opinfo); 1138 - rcu_read_unlock(); 1139 1126 1140 - if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) 1127 + if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) { 1128 + rcu_read_unlock(); 1141 1129 return; 1130 + } 1131 + rcu_read_unlock(); 1142 1132 1143 1133 p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); 1144 1134 if (!p_ci) ··· 1291 1277 set_oplock_level(opinfo, req_op_level, lctx); 1292 1278 1293 1279 out: 1294 - rcu_assign_pointer(fp->f_opinfo, opinfo); 1295 - opinfo->o_fp = fp; 1296 - 1297 1280 opinfo_count_inc(fp); 1298 - opinfo_add(opinfo); 1281 + opinfo_add(opinfo, fp); 1282 + 1299 1283 if (opinfo->is_lease) { 1300 1284 err = add_lease_global_list(opinfo); 1301 1285 if (err) 1302 1286 goto err_out; 1303 1287 } 1304 1288 1289 + rcu_assign_pointer(fp->f_opinfo, opinfo); 1290 + opinfo->o_fp = fp; 1291 + 1305 1292 return 0; 1306 1293 err_out: 1307 - free_opinfo(opinfo); 1294 + __free_opinfo(opinfo); 1308 1295 return err; 1309 1296 } 1310 1297
+3 -2
fs/smb/server/oplock.h
··· 69 69 struct lease *o_lease; 70 70 struct list_head op_entry; 71 71 struct list_head lease_entry; 72 - wait_queue_head_t oplock_q; /* Other server threads */ 73 - wait_queue_head_t oplock_brk; /* oplock breaking wait */ 72 + wait_queue_head_t oplock_q; /* Other server threads */ 73 + wait_queue_head_t oplock_brk; /* oplock breaking wait */ 74 + struct rcu_head rcu; 74 75 }; 75 76 76 77 struct lease_break_info {
+4 -4
fs/smb/server/smb2pdu.c
··· 3012 3012 goto err_out2; 3013 3013 } 3014 3014 3015 + fp = dh_info.fp; 3016 + 3015 3017 if (ksmbd_override_fsids(work)) { 3016 3018 rc = -ENOMEM; 3017 3019 ksmbd_put_durable_fd(dh_info.fp); 3018 3020 goto err_out2; 3019 3021 } 3020 3022 3021 - fp = dh_info.fp; 3022 3023 file_info = FILE_OPENED; 3023 3024 3024 3025 rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat); ··· 3617 3616 3618 3617 reconnected_fp: 3619 3618 rsp->StructureSize = cpu_to_le16(89); 3620 - rcu_read_lock(); 3621 - opinfo = rcu_dereference(fp->f_opinfo); 3619 + opinfo = opinfo_get(fp); 3622 3620 rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0; 3623 - rcu_read_unlock(); 3624 3621 rsp->Flags = 0; 3625 3622 rsp->CreateAction = cpu_to_le32(file_info); 3626 3623 rsp->CreationTime = cpu_to_le64(fp->create_time); ··· 3659 3660 next_ptr = &lease_ccontext->Next; 3660 3661 next_off = conn->vals->create_lease_size; 3661 3662 } 3663 + opinfo_put(opinfo); 3662 3664 3663 3665 if (maximal_access_ctxt) { 3664 3666 struct create_context *mxac_ccontext;
+5 -5
fs/smb/server/vfs_cache.c
··· 87 87 88 88 rcu_read_lock(); 89 89 opinfo = rcu_dereference(fp->f_opinfo); 90 - rcu_read_unlock(); 91 - 92 - if (!opinfo) { 93 - seq_printf(m, " %-15s", " "); 94 - } else { 90 + if (opinfo) { 95 91 const struct ksmbd_const_name *const_names; 96 92 int count; 97 93 unsigned int level; ··· 101 105 count = ARRAY_SIZE(ksmbd_oplock_const_names); 102 106 level = opinfo->level; 103 107 } 108 + rcu_read_unlock(); 104 109 ksmbd_proc_show_const_name(m, " %-15s", 105 110 const_names, count, level); 111 + } else { 112 + rcu_read_unlock(); 113 + seq_printf(m, " %-15s", " "); 106 114 } 107 115 108 116 seq_printf(m, " %#010x %#010x %s\n",