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 '6.17-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

- fix refcount issue that can cause memory leak

- rate limit repeated connections from IPv6, not just IPv4 addresses

- fix potential null pointer access of smb direct work queue

* tag '6.17-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: fix refcount leak causing resource not released
ksmbd: extend the connection limiting mechanism to support IPv6
smb: server: split ksmbd_rdma_stop_listening() out of ksmbd_rdma_destroy()

+48 -10
+2 -1
fs/smb/server/connection.c
··· 504 504 { 505 505 mutex_lock(&init_lock); 506 506 ksmbd_tcp_destroy(); 507 - ksmbd_rdma_destroy(); 507 + ksmbd_rdma_stop_listening(); 508 508 stop_sessions(); 509 + ksmbd_rdma_destroy(); 509 510 mutex_unlock(&init_lock); 510 511 }
+6 -1
fs/smb/server/connection.h
··· 46 46 struct mutex srv_mutex; 47 47 int status; 48 48 unsigned int cli_cap; 49 - __be32 inet_addr; 49 + union { 50 + __be32 inet_addr; 51 + #if IS_ENABLED(CONFIG_IPV6) 52 + u8 inet6_addr[16]; 53 + #endif 54 + }; 50 55 char *request_buf; 51 56 struct ksmbd_transport *transport; 52 57 struct nls_table *local_nls;
+10 -3
fs/smb/server/oplock.c
··· 1102 1102 if (!atomic_inc_not_zero(&opinfo->refcount)) 1103 1103 continue; 1104 1104 1105 - if (ksmbd_conn_releasing(opinfo->conn)) 1105 + if (ksmbd_conn_releasing(opinfo->conn)) { 1106 + opinfo_put(opinfo); 1106 1107 continue; 1108 + } 1107 1109 1108 1110 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); 1109 1111 opinfo_put(opinfo); ··· 1141 1139 if (!atomic_inc_not_zero(&opinfo->refcount)) 1142 1140 continue; 1143 1141 1144 - if (ksmbd_conn_releasing(opinfo->conn)) 1142 + if (ksmbd_conn_releasing(opinfo->conn)) { 1143 + opinfo_put(opinfo); 1145 1144 continue; 1145 + } 1146 + 1146 1147 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); 1147 1148 opinfo_put(opinfo); 1148 1149 } ··· 1348 1343 if (!atomic_inc_not_zero(&brk_op->refcount)) 1349 1344 continue; 1350 1345 1351 - if (ksmbd_conn_releasing(brk_op->conn)) 1346 + if (ksmbd_conn_releasing(brk_op->conn)) { 1347 + opinfo_put(brk_op); 1352 1348 continue; 1349 + } 1353 1350 1354 1351 if (brk_op->is_lease && (brk_op->o_lease->state & 1355 1352 (~(SMB2_LEASE_READ_CACHING_LE |
+4 -1
fs/smb/server/transport_rdma.c
··· 2194 2194 return 0; 2195 2195 } 2196 2196 2197 - void ksmbd_rdma_destroy(void) 2197 + void ksmbd_rdma_stop_listening(void) 2198 2198 { 2199 2199 if (!smb_direct_listener.cm_id) 2200 2200 return; ··· 2203 2203 rdma_destroy_id(smb_direct_listener.cm_id); 2204 2204 2205 2205 smb_direct_listener.cm_id = NULL; 2206 + } 2206 2207 2208 + void ksmbd_rdma_destroy(void) 2209 + { 2207 2210 if (smb_direct_wq) { 2208 2211 destroy_workqueue(smb_direct_wq); 2209 2212 smb_direct_wq = NULL;
+3 -1
fs/smb/server/transport_rdma.h
··· 54 54 55 55 #ifdef CONFIG_SMB_SERVER_SMBDIRECT 56 56 int ksmbd_rdma_init(void); 57 + void ksmbd_rdma_stop_listening(void); 57 58 void ksmbd_rdma_destroy(void); 58 59 bool ksmbd_rdma_capable_netdev(struct net_device *netdev); 59 60 void init_smbd_max_io_size(unsigned int sz); 60 61 unsigned int get_smbd_max_read_write_size(void); 61 62 #else 62 63 static inline int ksmbd_rdma_init(void) { return 0; } 63 - static inline int ksmbd_rdma_destroy(void) { return 0; } 64 + static inline void ksmbd_rdma_stop_listening(void) { } 65 + static inline void ksmbd_rdma_destroy(void) { } 64 66 static inline bool ksmbd_rdma_capable_netdev(struct net_device *netdev) { return false; } 65 67 static inline void init_smbd_max_io_size(unsigned int sz) { } 66 68 static inline unsigned int get_smbd_max_read_write_size(void) { return 0; }
+23 -3
fs/smb/server/transport_tcp.c
··· 85 85 return NULL; 86 86 } 87 87 88 + #if IS_ENABLED(CONFIG_IPV6) 89 + if (client_sk->sk->sk_family == AF_INET6) 90 + memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16); 91 + else 92 + conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; 93 + #else 88 94 conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; 95 + #endif 89 96 conn->transport = KSMBD_TRANS(t); 90 97 KSMBD_TRANS(t)->conn = conn; 91 98 KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops; ··· 236 229 { 237 230 struct socket *client_sk = NULL; 238 231 struct interface *iface = (struct interface *)p; 239 - struct inet_sock *csk_inet; 240 232 struct ksmbd_conn *conn; 241 233 int ret; 242 234 ··· 258 252 /* 259 253 * Limits repeated connections from clients with the same IP. 260 254 */ 261 - csk_inet = inet_sk(client_sk->sk); 262 255 down_read(&conn_list_lock); 263 256 list_for_each_entry(conn, &conn_list, conns_list) 264 - if (csk_inet->inet_daddr == conn->inet_addr) { 257 + #if IS_ENABLED(CONFIG_IPV6) 258 + if (client_sk->sk->sk_family == AF_INET6) { 259 + if (memcmp(&client_sk->sk->sk_v6_daddr, 260 + &conn->inet6_addr, 16) == 0) { 261 + ret = -EAGAIN; 262 + break; 263 + } 264 + } else if (inet_sk(client_sk->sk)->inet_daddr == 265 + conn->inet_addr) { 265 266 ret = -EAGAIN; 266 267 break; 267 268 } 269 + #else 270 + if (inet_sk(client_sk->sk)->inet_daddr == 271 + conn->inet_addr) { 272 + ret = -EAGAIN; 273 + break; 274 + } 275 + #endif 268 276 up_read(&conn_list_lock); 269 277 if (ret == -EAGAIN) 270 278 continue;