FILE
transport_tcp.c
File preview with syntax highlighting.
linux-6.19.14/fs/smb/server/transport_tcp.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org> 4 * Copyright (C) 2018 Samsung Electronics Co., Ltd. 5 */ 6 7#include <linux/freezer.h> 8 9#include "smb_common.h" 10#include "server.h" 11#include "auth.h" 12#include "connection.h" 13#include "transport_tcp.h" 14 15#define IFACE_STATE_DOWN BIT(0) 16#define IFACE_STATE_CONFIGURED BIT(1) 17 18static atomic_t active_num_conn; 19 20struct interface { 21 struct task_struct *ksmbd_kthread; 22 struct socket *ksmbd_socket; 23 struct list_head entry; 24 char *name; 25 int state; 26}; 27 28static LIST_HEAD(iface_list); 29 30static int bind_additional_ifaces; 31 32struct tcp_transport { 33 struct ksmbd_transport transport; 34 struct socket *sock; 35 struct kvec *iov; 36 unsigned int nr_iov; 37}; 38 39static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops; 40 41static void tcp_stop_kthread(struct task_struct *kthread); 42static struct interface *alloc_iface(char *ifname); 43static void ksmbd_tcp_disconnect(struct ksmbd_transport *t); 44 45#define KSMBD_TRANS(t) (&(t)->transport) 46#define TCP_TRANS(t) ((struct tcp_transport *)container_of(t, \ 47 struct tcp_transport, transport)) 48 49static inline void ksmbd_tcp_nodelay(struct socket *sock) 50{ 51 tcp_sock_set_nodelay(sock->sk); 52} 53 54static inline void ksmbd_tcp_reuseaddr(struct socket *sock) 55{ 56 sock_set_reuseaddr(sock->sk); 57} 58 59static struct tcp_transport *alloc_transport(struct socket *client_sk) 60{ 61 struct tcp_transport *t; 62 struct ksmbd_conn *conn; 63 64 t = kzalloc(sizeof(*t), KSMBD_DEFAULT_GFP); 65 if (!t) 66 return NULL; 67 t->sock = client_sk; 68 69 conn = ksmbd_conn_alloc(); 70 if (!conn) { 71 kfree(t); 72 return NULL; 73 } 74 75#if IS_ENABLED(CONFIG_IPV6) 76 if (client_sk->sk->sk_family == AF_INET6) { 77 memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16); 78 conn->inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); 79 } else { 80 conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; 81 conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); 82 } 83#else 84 conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; 85 conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); 86#endif 87 down_write(&conn_list_lock); 88 hash_add(conn_list, &conn->hlist, conn->inet_hash); 89 up_write(&conn_list_lock); 90 91 conn->transport = KSMBD_TRANS(t); 92 KSMBD_TRANS(t)->conn = conn; 93 KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops; 94 return t; 95} 96 97static void ksmbd_tcp_free_transport(struct ksmbd_transport *kt) 98{ 99 struct tcp_transport *t = TCP_TRANS(kt); 100 101 sock_release(t->sock); 102 kfree(t->iov); 103 kfree(t); 104} 105 106static void free_transport(struct tcp_transport *t) 107{ 108 kernel_sock_shutdown(t->sock, SHUT_RDWR); 109 ksmbd_conn_free(KSMBD_TRANS(t)->conn); 110} 111 112/** 113 * kvec_array_init() - initialize a IO vector segment 114 * @new: IO vector to be initialized 115 * @iov: base IO vector 116 * @nr_segs: number of segments in base iov 117 * @bytes: total iovec length so far for read 118 * 119 * Return: Number of IO segments 120 */ 121static unsigned int kvec_array_init(struct kvec *new, struct kvec *iov, 122 unsigned int nr_segs, size_t bytes) 123{ 124 size_t base = 0; 125 126 while (bytes || !iov->iov_len) { 127 int copy = min(bytes, iov->iov_len); 128 129 bytes -= copy; 130 base += copy; 131 if (iov->iov_len == base) { 132 iov++; 133 nr_segs--; 134 base = 0; 135 } 136 } 137 138 memcpy(new, iov, sizeof(*iov) * nr_segs); 139 new->iov_base += base; 140 new->iov_len -= base; 141 return nr_segs; 142} 143 144/** 145 * get_conn_iovec() - get connection iovec for reading from socket 146 * @t: TCP transport instance 147 * @nr_segs: number of segments in iov 148 * 149 * Return: return existing or newly allocate iovec 150 */ 151static struct kvec *get_conn_iovec(struct tcp_transport *t, unsigned int nr_segs) 152{ 153 struct kvec *new_iov; 154 155 if (t->iov && nr_segs <= t->nr_iov) 156 return t->iov; 157 158 /* not big enough -- allocate a new one and release the old */ 159 new_iov = kmalloc_array(nr_segs, sizeof(*new_iov), KSMBD_DEFAULT_GFP); 160 if (new_iov) { 161 kfree(t->iov); 162 t->iov = new_iov; 163 t->nr_iov = nr_segs; 164 } 165 return new_iov; 166} 167 168/** 169 * ksmbd_tcp_new_connection() - create a new tcp session on mount 170 * @client_sk: socket associated with new connection 171 * 172 * whenever a new connection is requested, create a conn thread 173 * (session thread) to handle new incoming smb requests from the connection 174 * 175 * Return: 0 on success, otherwise error 176 */ 177static int ksmbd_tcp_new_connection(struct socket *client_sk) 178{ 179 int rc = 0; 180 struct tcp_transport *t; 181 struct task_struct *handler; 182 183 t = alloc_transport(client_sk); 184 if (!t) { 185 sock_release(client_sk); 186 return -ENOMEM; 187 } 188 189#if IS_ENABLED(CONFIG_IPV6) 190 if (client_sk->sk->sk_family == AF_INET6) 191 handler = kthread_run(ksmbd_conn_handler_loop, 192 KSMBD_TRANS(t)->conn, "ksmbd:%pI6c", 193 &KSMBD_TRANS(t)->conn->inet6_addr); 194 else 195 handler = kthread_run(ksmbd_conn_handler_loop, 196 KSMBD_TRANS(t)->conn, "ksmbd:%pI4", 197 &KSMBD_TRANS(t)->conn->inet_addr); 198#else 199 handler = kthread_run(ksmbd_conn_handler_loop, 200 KSMBD_TRANS(t)->conn, "ksmbd:%pI4", 201 &KSMBD_TRANS(t)->conn->inet_addr); 202#endif 203 if (IS_ERR(handler)) { 204 pr_err("cannot start conn thread\n"); 205 rc = PTR_ERR(handler); 206 ksmbd_tcp_disconnect(KSMBD_TRANS(t)); 207 } 208 return rc; 209} 210 211/** 212 * ksmbd_kthread_fn() - listen to new SMB connections and callback server 213 * @p: arguments to forker thread 214 * 215 * Return: 0 on success, error number otherwise 216 */ 217static int ksmbd_kthread_fn(void *p) 218{ 219 struct socket *client_sk = NULL; 220 struct interface *iface = (struct interface *)p; 221 struct ksmbd_conn *conn; 222 int ret, inet_hash; 223 unsigned int max_ip_conns; 224 225 while (!kthread_should_stop()) { 226 if (!iface->ksmbd_socket) { 227 break; 228 } 229 ret = kernel_accept(iface->ksmbd_socket, &client_sk, 0); 230 if (ret == -EINVAL) 231 break; 232 if (ret) 233 continue; 234 235 if (!server_conf.max_ip_connections) 236 goto skip_max_ip_conns_limit; 237 238 /* 239 * Limits repeated connections from clients with the same IP. 240 */ 241#if IS_ENABLED(CONFIG_IPV6) 242 if (client_sk->sk->sk_family == AF_INET6) 243 inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); 244 else 245 inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); 246#else 247 inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); 248#endif 249 250 max_ip_conns = 0; 251 down_read(&conn_list_lock); 252 hash_for_each_possible(conn_list, conn, hlist, inet_hash) { 253#if IS_ENABLED(CONFIG_IPV6) 254 if (client_sk->sk->sk_family == AF_INET6) { 255 if (memcmp(&client_sk->sk->sk_v6_daddr, 256 &conn->inet6_addr, 16) == 0) 257 max_ip_conns++; 258 } else if (inet_sk(client_sk->sk)->inet_daddr == 259 conn->inet_addr) 260 max_ip_conns++; 261#else 262 if (inet_sk(client_sk->sk)->inet_daddr == 263 conn->inet_addr) 264 max_ip_conns++; 265#endif 266 if (server_conf.max_ip_connections <= max_ip_conns) { 267 pr_info_ratelimited("Maximum IP connections exceeded (%u/%u)\n", 268 max_ip_conns, server_conf.max_ip_connections); 269 ret = -EAGAIN; 270 break; 271 } 272 } 273 up_read(&conn_list_lock); 274 if (ret == -EAGAIN) { 275 /* Per-IP limit hit: release the just-accepted socket. */ 276 sock_release(client_sk); 277 continue; 278 } 279 280skip_max_ip_conns_limit: 281 if (server_conf.max_connections && 282 atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { 283 pr_info_ratelimited("Limit the maximum number of connections(%u)\n", 284 atomic_read(&active_num_conn)); 285 atomic_dec(&active_num_conn); 286 sock_release(client_sk); 287 continue; 288 } 289 290 ksmbd_debug(CONN, "connect success: accepted new connection\n"); 291 client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT; 292 client_sk->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT; 293 294 ksmbd_tcp_new_connection(client_sk); 295 } 296 297 ksmbd_debug(CONN, "releasing socket\n"); 298 return 0; 299} 300 301/** 302 * ksmbd_tcp_run_kthread() - start forker thread 303 * @iface: pointer to struct interface 304 * 305 * start forker thread(ksmbd/0) at module init time to listen 306 * on port 445 for new SMB connection requests. It creates per connection 307 * server threads(ksmbd/x) 308 * 309 * Return: 0 on success or error number 310 */ 311static int ksmbd_tcp_run_kthread(struct interface *iface) 312{ 313 int rc; 314 struct task_struct *kthread; 315 316 kthread = kthread_run(ksmbd_kthread_fn, (void *)iface, "ksmbd-%s", 317 iface->name); 318 if (IS_ERR(kthread)) { 319 rc = PTR_ERR(kthread); 320 return rc; 321 } 322 iface->ksmbd_kthread = kthread; 323 324 return 0; 325} 326 327/** 328 * ksmbd_tcp_readv() - read data from socket in given iovec 329 * @t: TCP transport instance 330 * @iov_orig: base IO vector 331 * @nr_segs: number of segments in base iov 332 * @to_read: number of bytes to read from socket 333 * @max_retries: maximum retry count 334 * 335 * Return: on success return number of bytes read from socket, 336 * otherwise return error number 337 */ 338static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig, 339 unsigned int nr_segs, unsigned int to_read, 340 int max_retries) 341{ 342 int length = 0; 343 int total_read; 344 unsigned int segs; 345 struct msghdr ksmbd_msg; 346 struct kvec *iov; 347 struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn; 348 349 iov = get_conn_iovec(t, nr_segs); 350 if (!iov) 351 return -ENOMEM; 352 353 ksmbd_msg.msg_control = NULL; 354 ksmbd_msg.msg_controllen = 0; 355 356 for (total_read = 0; to_read; total_read += length, to_read -= length) { 357 try_to_freeze(); 358 359 if (!ksmbd_conn_alive(conn)) { 360 total_read = -ESHUTDOWN; 361 break; 362 } 363 segs = kvec_array_init(iov, iov_orig, nr_segs, total_read); 364 365 length = kernel_recvmsg(t->sock, &ksmbd_msg, 366 iov, segs, to_read, 0); 367 368 if (length == -EINTR) { 369 total_read = -ESHUTDOWN; 370 break; 371 } else if (ksmbd_conn_need_reconnect(conn)) { 372 total_read = -EAGAIN; 373 break; 374 } else if (length == -ERESTARTSYS || length == -EAGAIN) { 375 /* 376 * If max_retries is negative, Allow unlimited 377 * retries to keep connection with inactive sessions. 378 */ 379 if (max_retries == 0) { 380 total_read = length; 381 break; 382 } else if (max_retries > 0) { 383 max_retries--; 384 } 385 386 usleep_range(1000, 2000); 387 length = 0; 388 continue; 389 } else if (length <= 0) { 390 total_read = length; 391 break; 392 } 393 } 394 return total_read; 395} 396 397/** 398 * ksmbd_tcp_read() - read data from socket in given buffer 399 * @t: TCP transport instance 400 * @buf: buffer to store read data from socket 401 * @to_read: number of bytes to read from socket 402 * @max_retries: number of retries if reading from socket fails 403 * 404 * Return: on success return number of bytes read from socket, 405 * otherwise return error number 406 */ 407static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, 408 unsigned int to_read, int max_retries) 409{ 410 struct kvec iov; 411 412 iov.iov_base = buf; 413 iov.iov_len = to_read; 414 415 return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries); 416} 417 418static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov, 419 int nvecs, int size, bool need_invalidate, 420 unsigned int remote_key) 421 422{ 423 struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL}; 424 425 return kernel_sendmsg(TCP_TRANS(t)->sock, &smb_msg, iov, nvecs, size); 426} 427 428static void ksmbd_tcp_disconnect(struct ksmbd_transport *t) 429{ 430 free_transport(TCP_TRANS(t)); 431 if (server_conf.max_connections) 432 atomic_dec(&active_num_conn); 433} 434 435static void tcp_destroy_socket(struct socket *ksmbd_socket) 436{ 437 int ret; 438 439 if (!ksmbd_socket) 440 return; 441 442 ret = kernel_sock_shutdown(ksmbd_socket, SHUT_RDWR); 443 if (ret) 444 pr_err("Failed to shutdown socket: %d\n", ret); 445 sock_release(ksmbd_socket); 446} 447 448/** 449 * create_socket - create socket for ksmbd/0 450 * @iface: interface to bind the created socket to 451 * 452 * Return: 0 on success, error number otherwise 453 */ 454static int create_socket(struct interface *iface) 455{ 456 int ret; 457 struct sockaddr_in6 sin6; 458 struct sockaddr_in sin; 459 struct socket *ksmbd_socket; 460 bool ipv4 = false; 461 462 ret = sock_create_kern(current->nsproxy->net_ns, PF_INET6, SOCK_STREAM, 463 IPPROTO_TCP, &ksmbd_socket); 464 if (ret) { 465 if (ret != -EAFNOSUPPORT) 466 pr_err("Can't create socket for ipv6, fallback to ipv4: %d\n", ret); 467 ret = sock_create_kern(current->nsproxy->net_ns, PF_INET, 468 SOCK_STREAM, IPPROTO_TCP, &ksmbd_socket); 469 if (ret) { 470 pr_err("Can't create socket for ipv4: %d\n", ret); 471 goto out_clear; 472 } 473 474 sin.sin_family = PF_INET; 475 sin.sin_addr.s_addr = htonl(INADDR_ANY); 476 sin.sin_port = htons(server_conf.tcp_port); 477 ipv4 = true; 478 } else { 479 sin6.sin6_family = PF_INET6; 480 sin6.sin6_addr = in6addr_any; 481 sin6.sin6_port = htons(server_conf.tcp_port); 482 483 lock_sock(ksmbd_socket->sk); 484 ksmbd_socket->sk->sk_ipv6only = false; 485 release_sock(ksmbd_socket->sk); 486 } 487 488 ksmbd_tcp_nodelay(ksmbd_socket); 489 ksmbd_tcp_reuseaddr(ksmbd_socket); 490 491 ret = sock_setsockopt(ksmbd_socket, 492 SOL_SOCKET, 493 SO_BINDTODEVICE, 494 KERNEL_SOCKPTR(iface->name), 495 strlen(iface->name)); 496 if (ret != -ENODEV && ret < 0) { 497 pr_err("Failed to set SO_BINDTODEVICE: %d\n", ret); 498 goto out_error; 499 } 500 501 if (ipv4) 502 ret = kernel_bind(ksmbd_socket, (struct sockaddr_unsized *)&sin, 503 sizeof(sin)); 504 else 505 ret = kernel_bind(ksmbd_socket, (struct sockaddr_unsized *)&sin6, 506 sizeof(sin6)); 507 if (ret) { 508 pr_err("Failed to bind socket: %d\n", ret); 509 goto out_error; 510 } 511 512 ret = kernel_listen(ksmbd_socket, KSMBD_SOCKET_BACKLOG); 513 if (ret) { 514 pr_err("Port listen() error: %d\n", ret); 515 goto out_error; 516 } 517 518 iface->ksmbd_socket = ksmbd_socket; 519 ret = ksmbd_tcp_run_kthread(iface); 520 if (ret) { 521 pr_err("Can't start ksmbd main kthread: %d\n", ret); 522 goto out_error; 523 } 524 iface->state = IFACE_STATE_CONFIGURED; 525 526 return 0; 527 528out_error: 529 tcp_destroy_socket(ksmbd_socket); 530out_clear: 531 iface->ksmbd_socket = NULL; 532 return ret; 533} 534 535struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name) 536{ 537 struct interface *iface; 538 539 list_for_each_entry(iface, &iface_list, entry) 540 if (!strcmp(iface->name, netdev_name)) 541 return iface; 542 return NULL; 543} 544 545static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, 546 void *ptr) 547{ 548 struct net_device *netdev = netdev_notifier_info_to_dev(ptr); 549 struct interface *iface; 550 int ret; 551 552 switch (event) { 553 case NETDEV_UP: 554 if (netif_is_bridge_port(netdev)) 555 return NOTIFY_OK; 556 557 iface = ksmbd_find_netdev_name_iface_list(netdev->name); 558 if (iface && iface->state == IFACE_STATE_DOWN) { 559 ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n", 560 iface->name); 561 ret = create_socket(iface); 562 if (ret) 563 return NOTIFY_OK; 564 } 565 if (!iface && bind_additional_ifaces) { 566 iface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP)); 567 if (!iface) 568 return NOTIFY_OK; 569 ksmbd_debug(CONN, "netdev-up event: netdev(%s) is going up\n", 570 iface->name); 571 ret = create_socket(iface); 572 if (ret) 573 break; 574 } 575 break; 576 case NETDEV_DOWN: 577 iface = ksmbd_find_netdev_name_iface_list(netdev->name); 578 if (iface && iface->state == IFACE_STATE_CONFIGURED) { 579 ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n", 580 iface->name); 581 kernel_sock_shutdown(iface->ksmbd_socket, SHUT_RDWR); 582 tcp_stop_kthread(iface->ksmbd_kthread); 583 iface->ksmbd_kthread = NULL; 584 sock_release(iface->ksmbd_socket); 585 iface->ksmbd_socket = NULL; 586 587 iface->state = IFACE_STATE_DOWN; 588 break; 589 } 590 break; 591 } 592 593 return NOTIFY_DONE; 594} 595 596static struct notifier_block ksmbd_netdev_notifier = { 597 .notifier_call = ksmbd_netdev_event, 598}; 599 600int ksmbd_tcp_init(void) 601{ 602 register_netdevice_notifier(&ksmbd_netdev_notifier); 603 604 return 0; 605} 606 607static void tcp_stop_kthread(struct task_struct *kthread) 608{ 609 int ret; 610 611 if (!kthread) 612 return; 613 614 ret = kthread_stop(kthread); 615 if (ret) 616 pr_err("failed to stop forker thread\n"); 617} 618 619void ksmbd_tcp_destroy(void) 620{ 621 struct interface *iface, *tmp; 622 623 unregister_netdevice_notifier(&ksmbd_netdev_notifier); 624 625 list_for_each_entry_safe(iface, tmp, &iface_list, entry) { 626 list_del(&iface->entry); 627 kfree(iface->name); 628 kfree(iface); 629 } 630} 631 632static struct interface *alloc_iface(char *ifname) 633{ 634 struct interface *iface; 635 636 if (!ifname) 637 return NULL; 638 639 iface = kzalloc(sizeof(struct interface), KSMBD_DEFAULT_GFP); 640 if (!iface) { 641 kfree(ifname); 642 return NULL; 643 } 644 645 iface->name = ifname; 646 iface->state = IFACE_STATE_DOWN; 647 list_add(&iface->entry, &iface_list); 648 return iface; 649} 650 651int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz) 652{ 653 int sz = 0; 654 655 if (!ifc_list_sz) { 656 bind_additional_ifaces = 1; 657 return 0; 658 } 659 660 while (ifc_list_sz > 0) { 661 if (!alloc_iface(kstrdup(ifc_list, KSMBD_DEFAULT_GFP))) 662 return -ENOMEM; 663 664 sz = strlen(ifc_list); 665 if (!sz) 666 break; 667 668 ifc_list += sz + 1; 669 ifc_list_sz -= (sz + 1); 670 } 671 672 bind_additional_ifaces = 0; 673 674 return 0; 675} 676 677static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops = { 678 .read = ksmbd_tcp_read, 679 .writev = ksmbd_tcp_writev, 680 .disconnect = ksmbd_tcp_disconnect, 681 .free_transport = ksmbd_tcp_free_transport, 682};
~/
Read-only file preview.