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.

at v6.2 638 lines 15 kB view raw
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 struct mutex sock_release_lock; 26 int state; 27}; 28 29static LIST_HEAD(iface_list); 30 31static int bind_additional_ifaces; 32 33struct tcp_transport { 34 struct ksmbd_transport transport; 35 struct socket *sock; 36 struct kvec *iov; 37 unsigned int nr_iov; 38}; 39 40static struct ksmbd_transport_ops ksmbd_tcp_transport_ops; 41 42static void tcp_stop_kthread(struct task_struct *kthread); 43static struct interface *alloc_iface(char *ifname); 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 inline void ksmbd_tcp_rcv_timeout(struct socket *sock, s64 secs) 60{ 61 lock_sock(sock->sk); 62 if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1) 63 sock->sk->sk_rcvtimeo = secs * HZ; 64 else 65 sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; 66 release_sock(sock->sk); 67} 68 69static inline void ksmbd_tcp_snd_timeout(struct socket *sock, s64 secs) 70{ 71 sock_set_sndtimeo(sock->sk, secs); 72} 73 74static struct tcp_transport *alloc_transport(struct socket *client_sk) 75{ 76 struct tcp_transport *t; 77 struct ksmbd_conn *conn; 78 79 t = kzalloc(sizeof(*t), GFP_KERNEL); 80 if (!t) 81 return NULL; 82 t->sock = client_sk; 83 84 conn = ksmbd_conn_alloc(); 85 if (!conn) { 86 kfree(t); 87 return NULL; 88 } 89 90 conn->transport = KSMBD_TRANS(t); 91 KSMBD_TRANS(t)->conn = conn; 92 KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops; 93 return t; 94} 95 96static void free_transport(struct tcp_transport *t) 97{ 98 kernel_sock_shutdown(t->sock, SHUT_RDWR); 99 sock_release(t->sock); 100 t->sock = NULL; 101 102 ksmbd_conn_free(KSMBD_TRANS(t)->conn); 103 kfree(t->iov); 104 kfree(t); 105} 106 107/** 108 * kvec_array_init() - initialize a IO vector segment 109 * @new: IO vector to be initialized 110 * @iov: base IO vector 111 * @nr_segs: number of segments in base iov 112 * @bytes: total iovec length so far for read 113 * 114 * Return: Number of IO segments 115 */ 116static unsigned int kvec_array_init(struct kvec *new, struct kvec *iov, 117 unsigned int nr_segs, size_t bytes) 118{ 119 size_t base = 0; 120 121 while (bytes || !iov->iov_len) { 122 int copy = min(bytes, iov->iov_len); 123 124 bytes -= copy; 125 base += copy; 126 if (iov->iov_len == base) { 127 iov++; 128 nr_segs--; 129 base = 0; 130 } 131 } 132 133 memcpy(new, iov, sizeof(*iov) * nr_segs); 134 new->iov_base += base; 135 new->iov_len -= base; 136 return nr_segs; 137} 138 139/** 140 * get_conn_iovec() - get connection iovec for reading from socket 141 * @t: TCP transport instance 142 * @nr_segs: number of segments in iov 143 * 144 * Return: return existing or newly allocate iovec 145 */ 146static struct kvec *get_conn_iovec(struct tcp_transport *t, unsigned int nr_segs) 147{ 148 struct kvec *new_iov; 149 150 if (t->iov && nr_segs <= t->nr_iov) 151 return t->iov; 152 153 /* not big enough -- allocate a new one and release the old */ 154 new_iov = kmalloc_array(nr_segs, sizeof(*new_iov), GFP_KERNEL); 155 if (new_iov) { 156 kfree(t->iov); 157 t->iov = new_iov; 158 t->nr_iov = nr_segs; 159 } 160 return new_iov; 161} 162 163static unsigned short ksmbd_tcp_get_port(const struct sockaddr *sa) 164{ 165 switch (sa->sa_family) { 166 case AF_INET: 167 return ntohs(((struct sockaddr_in *)sa)->sin_port); 168 case AF_INET6: 169 return ntohs(((struct sockaddr_in6 *)sa)->sin6_port); 170 } 171 return 0; 172} 173 174/** 175 * ksmbd_tcp_new_connection() - create a new tcp session on mount 176 * @client_sk: socket associated with new connection 177 * 178 * whenever a new connection is requested, create a conn thread 179 * (session thread) to handle new incoming smb requests from the connection 180 * 181 * Return: 0 on success, otherwise error 182 */ 183static int ksmbd_tcp_new_connection(struct socket *client_sk) 184{ 185 struct sockaddr *csin; 186 int rc = 0; 187 struct tcp_transport *t; 188 189 t = alloc_transport(client_sk); 190 if (!t) { 191 sock_release(client_sk); 192 return -ENOMEM; 193 } 194 195 csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn); 196 if (kernel_getpeername(client_sk, csin) < 0) { 197 pr_err("client ip resolution failed\n"); 198 rc = -EINVAL; 199 goto out_error; 200 } 201 202 KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, 203 KSMBD_TRANS(t)->conn, 204 "ksmbd:%u", 205 ksmbd_tcp_get_port(csin)); 206 if (IS_ERR(KSMBD_TRANS(t)->handler)) { 207 pr_err("cannot start conn thread\n"); 208 rc = PTR_ERR(KSMBD_TRANS(t)->handler); 209 free_transport(t); 210 } 211 return rc; 212 213out_error: 214 free_transport(t); 215 return rc; 216} 217 218/** 219 * ksmbd_kthread_fn() - listen to new SMB connections and callback server 220 * @p: arguments to forker thread 221 * 222 * Return: 0 on success, error number otherwise 223 */ 224static int ksmbd_kthread_fn(void *p) 225{ 226 struct socket *client_sk = NULL; 227 struct interface *iface = (struct interface *)p; 228 int ret; 229 230 while (!kthread_should_stop()) { 231 mutex_lock(&iface->sock_release_lock); 232 if (!iface->ksmbd_socket) { 233 mutex_unlock(&iface->sock_release_lock); 234 break; 235 } 236 ret = kernel_accept(iface->ksmbd_socket, &client_sk, 237 SOCK_NONBLOCK); 238 mutex_unlock(&iface->sock_release_lock); 239 if (ret) { 240 if (ret == -EAGAIN) 241 /* check for new connections every 100 msecs */ 242 schedule_timeout_interruptible(HZ / 10); 243 continue; 244 } 245 246 if (server_conf.max_connections && 247 atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { 248 pr_info_ratelimited("Limit the maximum number of connections(%u)\n", 249 atomic_read(&active_num_conn)); 250 atomic_dec(&active_num_conn); 251 sock_release(client_sk); 252 continue; 253 } 254 255 ksmbd_debug(CONN, "connect success: accepted new connection\n"); 256 client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT; 257 client_sk->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT; 258 259 ksmbd_tcp_new_connection(client_sk); 260 } 261 262 ksmbd_debug(CONN, "releasing socket\n"); 263 return 0; 264} 265 266/** 267 * ksmbd_tcp_run_kthread() - start forker thread 268 * @iface: pointer to struct interface 269 * 270 * start forker thread(ksmbd/0) at module init time to listen 271 * on port 445 for new SMB connection requests. It creates per connection 272 * server threads(ksmbd/x) 273 * 274 * Return: 0 on success or error number 275 */ 276static int ksmbd_tcp_run_kthread(struct interface *iface) 277{ 278 int rc; 279 struct task_struct *kthread; 280 281 kthread = kthread_run(ksmbd_kthread_fn, (void *)iface, "ksmbd-%s", 282 iface->name); 283 if (IS_ERR(kthread)) { 284 rc = PTR_ERR(kthread); 285 return rc; 286 } 287 iface->ksmbd_kthread = kthread; 288 289 return 0; 290} 291 292/** 293 * ksmbd_tcp_readv() - read data from socket in given iovec 294 * @t: TCP transport instance 295 * @iov_orig: base IO vector 296 * @nr_segs: number of segments in base iov 297 * @to_read: number of bytes to read from socket 298 * 299 * Return: on success return number of bytes read from socket, 300 * otherwise return error number 301 */ 302static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig, 303 unsigned int nr_segs, unsigned int to_read) 304{ 305 int length = 0; 306 int total_read; 307 unsigned int segs; 308 struct msghdr ksmbd_msg; 309 struct kvec *iov; 310 struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn; 311 int max_retry = 2; 312 313 iov = get_conn_iovec(t, nr_segs); 314 if (!iov) 315 return -ENOMEM; 316 317 ksmbd_msg.msg_control = NULL; 318 ksmbd_msg.msg_controllen = 0; 319 320 for (total_read = 0; to_read; total_read += length, to_read -= length) { 321 try_to_freeze(); 322 323 if (!ksmbd_conn_alive(conn)) { 324 total_read = -ESHUTDOWN; 325 break; 326 } 327 segs = kvec_array_init(iov, iov_orig, nr_segs, total_read); 328 329 length = kernel_recvmsg(t->sock, &ksmbd_msg, 330 iov, segs, to_read, 0); 331 332 if (length == -EINTR) { 333 total_read = -ESHUTDOWN; 334 break; 335 } else if (conn->status == KSMBD_SESS_NEED_RECONNECT) { 336 total_read = -EAGAIN; 337 break; 338 } else if ((length == -ERESTARTSYS || length == -EAGAIN) && 339 max_retry) { 340 usleep_range(1000, 2000); 341 length = 0; 342 max_retry--; 343 continue; 344 } else if (length <= 0) { 345 total_read = -EAGAIN; 346 break; 347 } 348 } 349 return total_read; 350} 351 352/** 353 * ksmbd_tcp_read() - read data from socket in given buffer 354 * @t: TCP transport instance 355 * @buf: buffer to store read data from socket 356 * @to_read: number of bytes to read from socket 357 * 358 * Return: on success return number of bytes read from socket, 359 * otherwise return error number 360 */ 361static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read) 362{ 363 struct kvec iov; 364 365 iov.iov_base = buf; 366 iov.iov_len = to_read; 367 368 return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read); 369} 370 371static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov, 372 int nvecs, int size, bool need_invalidate, 373 unsigned int remote_key) 374 375{ 376 struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL}; 377 378 return kernel_sendmsg(TCP_TRANS(t)->sock, &smb_msg, iov, nvecs, size); 379} 380 381static void ksmbd_tcp_disconnect(struct ksmbd_transport *t) 382{ 383 free_transport(TCP_TRANS(t)); 384 if (server_conf.max_connections) 385 atomic_dec(&active_num_conn); 386} 387 388static void tcp_destroy_socket(struct socket *ksmbd_socket) 389{ 390 int ret; 391 392 if (!ksmbd_socket) 393 return; 394 395 /* set zero to timeout */ 396 ksmbd_tcp_rcv_timeout(ksmbd_socket, 0); 397 ksmbd_tcp_snd_timeout(ksmbd_socket, 0); 398 399 ret = kernel_sock_shutdown(ksmbd_socket, SHUT_RDWR); 400 if (ret) 401 pr_err("Failed to shutdown socket: %d\n", ret); 402 sock_release(ksmbd_socket); 403} 404 405/** 406 * create_socket - create socket for ksmbd/0 407 * 408 * Return: 0 on success, error number otherwise 409 */ 410static int create_socket(struct interface *iface) 411{ 412 int ret; 413 struct sockaddr_in6 sin6; 414 struct sockaddr_in sin; 415 struct socket *ksmbd_socket; 416 bool ipv4 = false; 417 418 ret = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &ksmbd_socket); 419 if (ret) { 420 if (ret != -EAFNOSUPPORT) 421 pr_err("Can't create socket for ipv6, fallback to ipv4: %d\n", ret); 422 ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, 423 &ksmbd_socket); 424 if (ret) { 425 pr_err("Can't create socket for ipv4: %d\n", ret); 426 goto out_clear; 427 } 428 429 sin.sin_family = PF_INET; 430 sin.sin_addr.s_addr = htonl(INADDR_ANY); 431 sin.sin_port = htons(server_conf.tcp_port); 432 ipv4 = true; 433 } else { 434 sin6.sin6_family = PF_INET6; 435 sin6.sin6_addr = in6addr_any; 436 sin6.sin6_port = htons(server_conf.tcp_port); 437 } 438 439 ksmbd_tcp_nodelay(ksmbd_socket); 440 ksmbd_tcp_reuseaddr(ksmbd_socket); 441 442 ret = sock_setsockopt(ksmbd_socket, 443 SOL_SOCKET, 444 SO_BINDTODEVICE, 445 KERNEL_SOCKPTR(iface->name), 446 strlen(iface->name)); 447 if (ret != -ENODEV && ret < 0) { 448 pr_err("Failed to set SO_BINDTODEVICE: %d\n", ret); 449 goto out_error; 450 } 451 452 if (ipv4) 453 ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin, 454 sizeof(sin)); 455 else 456 ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin6, 457 sizeof(sin6)); 458 if (ret) { 459 pr_err("Failed to bind socket: %d\n", ret); 460 goto out_error; 461 } 462 463 ksmbd_socket->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT; 464 ksmbd_socket->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT; 465 466 ret = kernel_listen(ksmbd_socket, KSMBD_SOCKET_BACKLOG); 467 if (ret) { 468 pr_err("Port listen() error: %d\n", ret); 469 goto out_error; 470 } 471 472 iface->ksmbd_socket = ksmbd_socket; 473 ret = ksmbd_tcp_run_kthread(iface); 474 if (ret) { 475 pr_err("Can't start ksmbd main kthread: %d\n", ret); 476 goto out_error; 477 } 478 iface->state = IFACE_STATE_CONFIGURED; 479 480 return 0; 481 482out_error: 483 tcp_destroy_socket(ksmbd_socket); 484out_clear: 485 iface->ksmbd_socket = NULL; 486 return ret; 487} 488 489static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, 490 void *ptr) 491{ 492 struct net_device *netdev = netdev_notifier_info_to_dev(ptr); 493 struct interface *iface; 494 int ret, found = 0; 495 496 switch (event) { 497 case NETDEV_UP: 498 if (netif_is_bridge_port(netdev)) 499 return NOTIFY_OK; 500 501 list_for_each_entry(iface, &iface_list, entry) { 502 if (!strcmp(iface->name, netdev->name)) { 503 found = 1; 504 if (iface->state != IFACE_STATE_DOWN) 505 break; 506 ret = create_socket(iface); 507 if (ret) 508 return NOTIFY_OK; 509 break; 510 } 511 } 512 if (!found && bind_additional_ifaces) { 513 iface = alloc_iface(kstrdup(netdev->name, GFP_KERNEL)); 514 if (!iface) 515 return NOTIFY_OK; 516 ret = create_socket(iface); 517 if (ret) 518 break; 519 } 520 break; 521 case NETDEV_DOWN: 522 list_for_each_entry(iface, &iface_list, entry) { 523 if (!strcmp(iface->name, netdev->name) && 524 iface->state == IFACE_STATE_CONFIGURED) { 525 tcp_stop_kthread(iface->ksmbd_kthread); 526 iface->ksmbd_kthread = NULL; 527 mutex_lock(&iface->sock_release_lock); 528 tcp_destroy_socket(iface->ksmbd_socket); 529 iface->ksmbd_socket = NULL; 530 mutex_unlock(&iface->sock_release_lock); 531 532 iface->state = IFACE_STATE_DOWN; 533 break; 534 } 535 } 536 break; 537 } 538 539 return NOTIFY_DONE; 540} 541 542static struct notifier_block ksmbd_netdev_notifier = { 543 .notifier_call = ksmbd_netdev_event, 544}; 545 546int ksmbd_tcp_init(void) 547{ 548 register_netdevice_notifier(&ksmbd_netdev_notifier); 549 550 return 0; 551} 552 553static void tcp_stop_kthread(struct task_struct *kthread) 554{ 555 int ret; 556 557 if (!kthread) 558 return; 559 560 ret = kthread_stop(kthread); 561 if (ret) 562 pr_err("failed to stop forker thread\n"); 563} 564 565void ksmbd_tcp_destroy(void) 566{ 567 struct interface *iface, *tmp; 568 569 unregister_netdevice_notifier(&ksmbd_netdev_notifier); 570 571 list_for_each_entry_safe(iface, tmp, &iface_list, entry) { 572 list_del(&iface->entry); 573 kfree(iface->name); 574 kfree(iface); 575 } 576} 577 578static struct interface *alloc_iface(char *ifname) 579{ 580 struct interface *iface; 581 582 if (!ifname) 583 return NULL; 584 585 iface = kzalloc(sizeof(struct interface), GFP_KERNEL); 586 if (!iface) { 587 kfree(ifname); 588 return NULL; 589 } 590 591 iface->name = ifname; 592 iface->state = IFACE_STATE_DOWN; 593 list_add(&iface->entry, &iface_list); 594 mutex_init(&iface->sock_release_lock); 595 return iface; 596} 597 598int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz) 599{ 600 int sz = 0; 601 602 if (!ifc_list_sz) { 603 struct net_device *netdev; 604 605 rtnl_lock(); 606 for_each_netdev(&init_net, netdev) { 607 if (netif_is_bridge_port(netdev)) 608 continue; 609 if (!alloc_iface(kstrdup(netdev->name, GFP_KERNEL))) 610 return -ENOMEM; 611 } 612 rtnl_unlock(); 613 bind_additional_ifaces = 1; 614 return 0; 615 } 616 617 while (ifc_list_sz > 0) { 618 if (!alloc_iface(kstrdup(ifc_list, GFP_KERNEL))) 619 return -ENOMEM; 620 621 sz = strlen(ifc_list); 622 if (!sz) 623 break; 624 625 ifc_list += sz + 1; 626 ifc_list_sz -= (sz + 1); 627 } 628 629 bind_additional_ifaces = 0; 630 631 return 0; 632} 633 634static struct ksmbd_transport_ops ksmbd_tcp_transport_ops = { 635 .read = ksmbd_tcp_read, 636 .writev = ksmbd_tcp_writev, 637 .disconnect = ksmbd_tcp_disconnect, 638};