1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2000,2005 5 * 6 * Modified by Steve French (sfrench@us.ibm.com) 7 */ 8 #include <linux/fs.h> 9 #include <linux/string.h> 10 #include <linux/ctype.h> 11 #include <linux/kstrtox.h> 12 #include <linux/module.h> 13 #include <linux/proc_fs.h> 14 #include <linux/uaccess.h> 15 #include <uapi/linux/ethtool.h> 16 #include "cifspdu.h" 17 #include "cifsglob.h" 18 #include "cifsproto.h" 19 #include "cifs_debug.h" 20 #include "cifsfs.h" 21 #include "fs_context.h" 22 #ifdef CONFIG_CIFS_DFS_UPCALL 23 #include "dfs_cache.h" 24 #endif 25 #ifdef CONFIG_CIFS_SMB_DIRECT 26 #include "smbdirect.h" 27 #endif 28 #include "cifs_swn.h" 29 #include "cached_dir.h" 30 31 void 32 cifs_dump_mem(char *label, void *data, int length) 33 { 34 pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data); 35 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, 36 data, length, true); 37 } 38 39 void cifs_dump_detail(void *buf, struct TCP_Server_Info *server) 40 { 41 #ifdef CONFIG_CIFS_DEBUG2 42 struct smb_hdr *smb = buf; 43 44 cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d Wct: %d\n", 45 smb->Command, smb->Status.CifsError, smb->Flags, 46 smb->Flags2, smb->Mid, smb->Pid, smb->WordCount); 47 if (!server->ops->check_message(buf, server->total_read, server)) { 48 cifs_dbg(VFS, "smb buf %p len %u\n", smb, 49 server->ops->calc_smb_size(smb)); 50 } 51 #endif /* CONFIG_CIFS_DEBUG2 */ 52 } 53 54 void cifs_dump_mids(struct TCP_Server_Info *server) 55 { 56 #ifdef CONFIG_CIFS_DEBUG2 57 struct mid_q_entry *mid_entry; 58 59 if (server == NULL) 60 return; 61 62 cifs_dbg(VFS, "Dump pending requests:\n"); 63 spin_lock(&server->mid_queue_lock); 64 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 65 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n", 66 mid_entry->mid_state, 67 le16_to_cpu(mid_entry->command), 68 mid_entry->pid, 69 mid_entry->callback_data, 70 mid_entry->mid); 71 #ifdef CONFIG_CIFS_STATS2 72 cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n", 73 mid_entry->large_buf, 74 mid_entry->resp_buf, 75 mid_entry->when_received, 76 jiffies); 77 #endif /* STATS2 */ 78 cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n", 79 mid_entry->multiRsp, mid_entry->multiEnd); 80 if (mid_entry->resp_buf) { 81 cifs_dump_detail(mid_entry->resp_buf, server); 82 cifs_dump_mem("existing buf: ", 83 mid_entry->resp_buf, 62); 84 } 85 } 86 spin_unlock(&server->mid_queue_lock); 87 #endif /* CONFIG_CIFS_DEBUG2 */ 88 } 89 90 #ifdef CONFIG_PROC_FS 91 static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon) 92 { 93 __u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 94 95 seq_printf(m, "%s Mounts: %d ", tcon->tree_name, tcon->tc_count); 96 if (tcon->nativeFileSystem) 97 seq_printf(m, "Type: %s ", tcon->nativeFileSystem); 98 seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d", 99 le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), 100 le32_to_cpu(tcon->fsAttrInfo.Attributes), 101 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), 102 tcon->status); 103 if (dev_type == FILE_DEVICE_DISK) 104 seq_puts(m, " type: DISK "); 105 else if (dev_type == FILE_DEVICE_CD_ROM) 106 seq_puts(m, " type: CDROM "); 107 else 108 seq_printf(m, " type: %d ", dev_type); 109 110 seq_printf(m, "Serial Number: 0x%x", tcon->vol_serial_number); 111 112 if ((tcon->seal) || 113 (tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) || 114 (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)) 115 seq_puts(m, " encrypted"); 116 if (tcon->nocase) 117 seq_printf(m, " nocase"); 118 if (tcon->unix_ext) 119 seq_printf(m, " POSIX Extensions"); 120 if (tcon->ses->server->ops->dump_share_caps) 121 tcon->ses->server->ops->dump_share_caps(m, tcon); 122 if (tcon->use_witness) 123 seq_puts(m, " Witness"); 124 if (tcon->broken_sparse_sup) 125 seq_puts(m, " nosparse"); 126 if (tcon->need_reconnect) 127 seq_puts(m, "\tDISCONNECTED "); 128 spin_lock(&tcon->tc_lock); 129 if (tcon->origin_fullpath) { 130 seq_printf(m, "\n\tDFS origin fullpath: %s", 131 tcon->origin_fullpath); 132 } 133 spin_unlock(&tcon->tc_lock); 134 seq_putc(m, '\n'); 135 } 136 137 static void 138 cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan) 139 { 140 struct TCP_Server_Info *server = chan->server; 141 142 if (!server) { 143 seq_printf(m, "\n\n\t\tChannel: %d DISABLED", i+1); 144 return; 145 } 146 147 seq_printf(m, "\n\n\t\tChannel: %d ConnectionId: 0x%llx" 148 "\n\t\tNumber of credits: %d,%d,%d Dialect 0x%x" 149 "\n\t\tTCP status: %d Instance: %d" 150 "\n\t\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d" 151 "\n\t\tIn Send: %d In MaxReq Wait: %d", 152 i+1, server->conn_id, 153 server->credits, 154 server->echo_credits, 155 server->oplock_credits, 156 server->dialect, 157 server->tcpStatus, 158 server->reconnect_instance, 159 server->srv_count, 160 server->sec_mode, 161 in_flight(server), 162 atomic_read(&server->in_send), 163 atomic_read(&server->num_waiters)); 164 #ifdef CONFIG_NET_NS 165 if (server->net) 166 seq_printf(m, " Net namespace: %u ", server->net->ns.inum); 167 #endif /* NET_NS */ 168 169 } 170 171 static inline const char *smb_speed_to_str(size_t bps) 172 { 173 size_t mbps = bps / 1000 / 1000; 174 175 switch (mbps) { 176 case SPEED_10: 177 return "10Mbps"; 178 case SPEED_100: 179 return "100Mbps"; 180 case SPEED_1000: 181 return "1Gbps"; 182 case SPEED_2500: 183 return "2.5Gbps"; 184 case SPEED_5000: 185 return "5Gbps"; 186 case SPEED_10000: 187 return "10Gbps"; 188 case SPEED_14000: 189 return "14Gbps"; 190 case SPEED_20000: 191 return "20Gbps"; 192 case SPEED_25000: 193 return "25Gbps"; 194 case SPEED_40000: 195 return "40Gbps"; 196 case SPEED_50000: 197 return "50Gbps"; 198 case SPEED_56000: 199 return "56Gbps"; 200 case SPEED_100000: 201 return "100Gbps"; 202 case SPEED_200000: 203 return "200Gbps"; 204 case SPEED_400000: 205 return "400Gbps"; 206 case SPEED_800000: 207 return "800Gbps"; 208 default: 209 return "Unknown"; 210 } 211 } 212 213 static void 214 cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface) 215 { 216 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr; 217 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr; 218 219 seq_printf(m, "\tSpeed: %s\n", smb_speed_to_str(iface->speed)); 220 seq_puts(m, "\t\tCapabilities: "); 221 if (iface->rdma_capable) 222 seq_puts(m, "rdma "); 223 if (iface->rss_capable) 224 seq_puts(m, "rss "); 225 if (!iface->rdma_capable && !iface->rss_capable) 226 seq_puts(m, "None"); 227 seq_putc(m, '\n'); 228 if (iface->sockaddr.ss_family == AF_INET) 229 seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr); 230 else if (iface->sockaddr.ss_family == AF_INET6) 231 seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr); 232 if (!iface->is_active) 233 seq_puts(m, "\t\t[for-cleanup]\n"); 234 } 235 236 static int cifs_debug_files_proc_show(struct seq_file *m, void *v) 237 { 238 struct TCP_Server_Info *server; 239 struct cifs_ses *ses; 240 struct cifs_tcon *tcon; 241 struct cifsFileInfo *cfile; 242 243 seq_puts(m, "# Version:1\n"); 244 seq_puts(m, "# Format:\n"); 245 seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>"); 246 #ifdef CONFIG_CIFS_DEBUG2 247 seq_printf(m, " <filename> <mid>\n"); 248 #else 249 seq_printf(m, " <filename>\n"); 250 #endif /* CIFS_DEBUG2 */ 251 spin_lock(&cifs_tcp_ses_lock); 252 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 253 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 254 if (cifs_ses_exiting(ses)) 255 continue; 256 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { 257 spin_lock(&tcon->open_file_lock); 258 list_for_each_entry(cfile, &tcon->openFileList, tlist) { 259 seq_printf(m, 260 "0x%x 0x%llx 0x%llx 0x%x %d %d %d %pd", 261 tcon->tid, 262 ses->Suid, 263 cfile->fid.persistent_fid, 264 cfile->f_flags, 265 cfile->count, 266 cfile->pid, 267 from_kuid(&init_user_ns, cfile->uid), 268 cfile->dentry); 269 #ifdef CONFIG_CIFS_DEBUG2 270 seq_printf(m, " %llu\n", cfile->fid.mid); 271 #else 272 seq_printf(m, "\n"); 273 #endif /* CIFS_DEBUG2 */ 274 } 275 spin_unlock(&tcon->open_file_lock); 276 } 277 } 278 } 279 spin_unlock(&cifs_tcp_ses_lock); 280 seq_putc(m, '\n'); 281 return 0; 282 } 283 284 static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v) 285 { 286 struct list_head *stmp, *tmp, *tmp1; 287 struct TCP_Server_Info *server; 288 struct cifs_ses *ses; 289 struct cifs_tcon *tcon; 290 struct cached_fids *cfids; 291 struct cached_fid *cfid; 292 LIST_HEAD(entry); 293 294 seq_puts(m, "# Version:1\n"); 295 seq_puts(m, "# Format:\n"); 296 seq_puts(m, "# <tree id> <sess id> <persistent fid> <path>\n"); 297 298 spin_lock(&cifs_tcp_ses_lock); 299 list_for_each(stmp, &cifs_tcp_ses_list) { 300 server = list_entry(stmp, struct TCP_Server_Info, 301 tcp_ses_list); 302 list_for_each(tmp, &server->smb_ses_list) { 303 ses = list_entry(tmp, struct cifs_ses, smb_ses_list); 304 list_for_each(tmp1, &ses->tcon_list) { 305 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list); 306 cfids = tcon->cfids; 307 if (!cfids) 308 continue; 309 spin_lock(&cfids->cfid_list_lock); /* check lock ordering */ 310 seq_printf(m, "Num entries: %d\n", cfids->num_entries); 311 list_for_each_entry(cfid, &cfids->entries, entry) { 312 seq_printf(m, "0x%x 0x%llx 0x%llx %s", 313 tcon->tid, 314 ses->Suid, 315 cfid->fid.persistent_fid, 316 cfid->path); 317 if (cfid->file_all_info_is_valid) 318 seq_printf(m, "\tvalid file info"); 319 if (cfid->dirents.is_valid) 320 seq_printf(m, ", valid dirents"); 321 seq_printf(m, "\n"); 322 } 323 spin_unlock(&cfids->cfid_list_lock); 324 } 325 } 326 } 327 spin_unlock(&cifs_tcp_ses_lock); 328 seq_putc(m, '\n'); 329 return 0; 330 } 331 332 static __always_inline const char *compression_alg_str(__le16 alg) 333 { 334 switch (alg) { 335 case SMB3_COMPRESS_NONE: 336 return "NONE"; 337 case SMB3_COMPRESS_LZNT1: 338 return "LZNT1"; 339 case SMB3_COMPRESS_LZ77: 340 return "LZ77"; 341 case SMB3_COMPRESS_LZ77_HUFF: 342 return "LZ77-Huffman"; 343 case SMB3_COMPRESS_PATTERN: 344 return "Pattern_V1"; 345 default: 346 return "invalid"; 347 } 348 } 349 350 static __always_inline const char *cipher_alg_str(__le16 cipher) 351 { 352 switch (cipher) { 353 case SMB2_ENCRYPTION_AES128_CCM: 354 return "AES128-CCM"; 355 case SMB2_ENCRYPTION_AES128_GCM: 356 return "AES128-GCM"; 357 case SMB2_ENCRYPTION_AES256_CCM: 358 return "AES256-CCM"; 359 case SMB2_ENCRYPTION_AES256_GCM: 360 return "AES256-GCM"; 361 default: 362 return "UNKNOWN"; 363 } 364 } 365 366 static int cifs_debug_data_proc_show(struct seq_file *m, void *v) 367 { 368 struct mid_q_entry *mid_entry; 369 struct TCP_Server_Info *server; 370 struct TCP_Server_Info *chan_server; 371 struct cifs_ses *ses; 372 struct cifs_tcon *tcon; 373 struct cifs_server_iface *iface; 374 size_t iface_weight = 0, iface_min_speed = 0; 375 struct cifs_server_iface *last_iface = NULL; 376 int c, i, j; 377 378 seq_puts(m, 379 "Display Internal CIFS Data Structures for Debugging\n" 380 "---------------------------------------------------\n"); 381 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); 382 seq_printf(m, "Features:"); 383 #ifdef CONFIG_CIFS_DFS_UPCALL 384 seq_printf(m, " DFS"); 385 #endif 386 #ifdef CONFIG_CIFS_FSCACHE 387 seq_printf(m, ",FSCACHE"); 388 #endif 389 #ifdef CONFIG_CIFS_SMB_DIRECT 390 seq_printf(m, ",SMB_DIRECT"); 391 #endif 392 #ifdef CONFIG_CIFS_STATS2 393 seq_printf(m, ",STATS2"); 394 #else 395 seq_printf(m, ",STATS"); 396 #endif 397 #ifdef CONFIG_CIFS_DEBUG2 398 seq_printf(m, ",DEBUG2"); 399 #elif defined(CONFIG_CIFS_DEBUG) 400 seq_printf(m, ",DEBUG"); 401 #endif 402 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 403 seq_printf(m, ",ALLOW_INSECURE_LEGACY"); 404 #endif 405 #ifdef CONFIG_CIFS_POSIX 406 seq_printf(m, ",CIFS_POSIX"); 407 #endif 408 #ifdef CONFIG_CIFS_UPCALL 409 seq_printf(m, ",UPCALL(SPNEGO)"); 410 #endif 411 #ifdef CONFIG_CIFS_XATTR 412 seq_printf(m, ",XATTR"); 413 #endif 414 seq_printf(m, ",ACL"); 415 #ifdef CONFIG_CIFS_SWN_UPCALL 416 seq_puts(m, ",WITNESS"); 417 #endif 418 #ifdef CONFIG_CIFS_COMPRESSION 419 seq_puts(m, ",COMPRESSION"); 420 #endif 421 seq_putc(m, '\n'); 422 seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize); 423 seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); 424 425 seq_printf(m, "\nServers: "); 426 427 c = 0; 428 spin_lock(&cifs_tcp_ses_lock); 429 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 430 #ifdef CONFIG_CIFS_SMB_DIRECT 431 struct smbdirect_socket *sc; 432 struct smbdirect_socket_parameters *sp; 433 #endif 434 435 /* channel info will be printed as a part of sessions below */ 436 if (SERVER_IS_CHAN(server)) 437 continue; 438 439 c++; 440 seq_printf(m, "\n%d) ConnectionId: 0x%llx ", 441 c, server->conn_id); 442 443 spin_lock(&server->srv_lock); 444 if (server->hostname) 445 seq_printf(m, "Hostname: %s ", server->hostname); 446 seq_printf(m, "\nClientGUID: %pUL", server->client_guid); 447 spin_unlock(&server->srv_lock); 448 #ifdef CONFIG_CIFS_SMB_DIRECT 449 if (!server->rdma) 450 goto skip_rdma; 451 452 if (!server->smbd_conn) { 453 seq_printf(m, "\nSMBDirect transport not available"); 454 goto skip_rdma; 455 } 456 sc = &server->smbd_conn->socket; 457 sp = &sc->parameters; 458 459 seq_printf(m, "\nSMBDirect (in hex) protocol version: %x " 460 "transport status: %x", 461 server->smbd_conn->protocol, 462 server->smbd_conn->socket.status); 463 seq_printf(m, "\nConn receive_credit_max: %x " 464 "send_credit_target: %x max_send_size: %x", 465 sp->recv_credit_max, 466 sp->send_credit_target, 467 sp->max_send_size); 468 seq_printf(m, "\nConn max_fragmented_recv_size: %x " 469 "max_fragmented_send_size: %x max_receive_size:%x", 470 sp->max_fragmented_recv_size, 471 sp->max_fragmented_send_size, 472 sp->max_recv_size); 473 seq_printf(m, "\nConn keep_alive_interval: %x " 474 "max_readwrite_size: %x rdma_readwrite_threshold: %x", 475 sp->keepalive_interval_msec * 1000, 476 sp->max_read_write_size, 477 server->smbd_conn->rdma_readwrite_threshold); 478 seq_printf(m, "\nDebug count_get_receive_buffer: %x " 479 "count_put_receive_buffer: %x count_send_empty: %x", 480 server->smbd_conn->count_get_receive_buffer, 481 server->smbd_conn->count_put_receive_buffer, 482 server->smbd_conn->count_send_empty); 483 seq_printf(m, "\nRead Queue count_reassembly_queue: %x " 484 "count_enqueue_reassembly_queue: %x " 485 "count_dequeue_reassembly_queue: %x " 486 "reassembly_data_length: %x " 487 "reassembly_queue_length: %x", 488 server->smbd_conn->count_reassembly_queue, 489 server->smbd_conn->count_enqueue_reassembly_queue, 490 server->smbd_conn->count_dequeue_reassembly_queue, 491 sc->recv_io.reassembly.data_length, 492 sc->recv_io.reassembly.queue_length); 493 seq_printf(m, "\nCurrent Credits send_credits: %x " 494 "receive_credits: %x receive_credit_target: %x", 495 atomic_read(&server->smbd_conn->send_credits), 496 atomic_read(&server->smbd_conn->receive_credits), 497 server->smbd_conn->receive_credit_target); 498 seq_printf(m, "\nPending send_pending: %x ", 499 atomic_read(&server->smbd_conn->send_pending)); 500 seq_printf(m, "\nReceive buffers count_receive_queue: %x ", 501 server->smbd_conn->count_receive_queue); 502 seq_printf(m, "\nMR responder_resources: %x " 503 "max_frmr_depth: %x mr_type: %x", 504 server->smbd_conn->responder_resources, 505 server->smbd_conn->max_frmr_depth, 506 server->smbd_conn->mr_type); 507 seq_printf(m, "\nMR mr_ready_count: %x mr_used_count: %x", 508 atomic_read(&server->smbd_conn->mr_ready_count), 509 atomic_read(&server->smbd_conn->mr_used_count)); 510 skip_rdma: 511 #endif 512 seq_printf(m, "\nNumber of credits: %d,%d,%d Dialect 0x%x", 513 server->credits, 514 server->echo_credits, 515 server->oplock_credits, 516 server->dialect); 517 if (server->sign) 518 seq_printf(m, " signed"); 519 if (server->posix_ext_supported) 520 seq_printf(m, " posix"); 521 if (server->nosharesock) 522 seq_printf(m, " nosharesock"); 523 524 seq_printf(m, "\nServer capabilities: 0x%x", server->capabilities); 525 526 if (server->rdma) 527 seq_printf(m, "\nRDMA "); 528 seq_printf(m, "\nTCP status: %d Instance: %d" 529 "\nLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d", 530 server->tcpStatus, 531 server->reconnect_instance, 532 server->srv_count, 533 server->sec_mode, in_flight(server)); 534 #ifdef CONFIG_NET_NS 535 if (server->net) 536 seq_printf(m, " Net namespace: %u ", server->net->ns.inum); 537 #endif /* NET_NS */ 538 539 seq_printf(m, "\nIn Send: %d In MaxReq Wait: %d", 540 atomic_read(&server->in_send), 541 atomic_read(&server->num_waiters)); 542 543 if (server->leaf_fullpath) { 544 seq_printf(m, "\nDFS leaf full path: %s", 545 server->leaf_fullpath); 546 } 547 548 seq_puts(m, "\nCompression: "); 549 if (!IS_ENABLED(CONFIG_CIFS_COMPRESSION)) 550 seq_puts(m, "no built-in support"); 551 else if (!server->compression.requested) 552 seq_puts(m, "disabled on mount"); 553 else if (server->compression.enabled) 554 seq_printf(m, "enabled (%s)", compression_alg_str(server->compression.alg)); 555 else 556 seq_puts(m, "disabled (not supported by this server)"); 557 558 /* Show negotiated encryption cipher, even if not required */ 559 seq_puts(m, "\nEncryption: "); 560 if (server->cipher_type) 561 seq_printf(m, "Negotiated cipher (%s)", cipher_alg_str(server->cipher_type)); 562 563 seq_printf(m, "\n\n\tSessions: "); 564 i = 0; 565 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 566 spin_lock(&ses->ses_lock); 567 if (ses->ses_status == SES_EXITING) { 568 spin_unlock(&ses->ses_lock); 569 continue; 570 } 571 i++; 572 if ((ses->serverDomain == NULL) || 573 (ses->serverOS == NULL) || 574 (ses->serverNOS == NULL)) { 575 seq_printf(m, "\n\t%d) Address: %s Uses: %d Capability: 0x%x\tSession Status: %d ", 576 i, ses->ip_addr, ses->ses_count, 577 ses->capabilities, ses->ses_status); 578 if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) 579 seq_printf(m, "Guest "); 580 else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) 581 seq_printf(m, "Anonymous "); 582 } else { 583 seq_printf(m, 584 "\n\t%d) Name: %s Domain: %s Uses: %d OS: %s " 585 "\n\tNOS: %s\tCapability: 0x%x" 586 "\n\tSMB session status: %d ", 587 i, ses->ip_addr, ses->serverDomain, 588 ses->ses_count, ses->serverOS, ses->serverNOS, 589 ses->capabilities, ses->ses_status); 590 } 591 if (ses->expired_pwd) 592 seq_puts(m, "password no longer valid "); 593 spin_unlock(&ses->ses_lock); 594 595 seq_printf(m, "\n\tSecurity type: %s ", 596 get_security_type_str(server->ops->select_sectype(server, ses->sectype))); 597 598 /* dump session id helpful for use with network trace */ 599 seq_printf(m, " SessionId: 0x%llx", ses->Suid); 600 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) 601 seq_puts(m, " encrypted"); 602 if (ses->sign) 603 seq_puts(m, " signed"); 604 605 seq_printf(m, "\n\tUser: %d Cred User: %d", 606 from_kuid(&init_user_ns, ses->linux_uid), 607 from_kuid(&init_user_ns, ses->cred_uid)); 608 609 if (ses->dfs_root_ses) { 610 seq_printf(m, "\n\tDFS root session id: 0x%llx", 611 ses->dfs_root_ses->Suid); 612 } 613 614 spin_lock(&ses->chan_lock); 615 if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0)) 616 seq_puts(m, "\tPrimary channel: DISCONNECTED "); 617 if (CIFS_CHAN_IN_RECONNECT(ses, 0)) 618 seq_puts(m, "\t[RECONNECTING] "); 619 620 if (ses->chan_count > 1) { 621 seq_printf(m, "\n\n\tExtra Channels: %zu ", 622 ses->chan_count-1); 623 for (j = 1; j < ses->chan_count; j++) { 624 cifs_dump_channel(m, j, &ses->chans[j]); 625 if (CIFS_CHAN_NEEDS_RECONNECT(ses, j)) 626 seq_puts(m, "\tDISCONNECTED "); 627 if (CIFS_CHAN_IN_RECONNECT(ses, j)) 628 seq_puts(m, "\t[RECONNECTING] "); 629 } 630 } 631 spin_unlock(&ses->chan_lock); 632 633 seq_puts(m, "\n\n\tShares: "); 634 j = 0; 635 636 seq_printf(m, "\n\t%d) IPC: ", j); 637 if (ses->tcon_ipc) 638 cifs_debug_tcon(m, ses->tcon_ipc); 639 else 640 seq_puts(m, "none\n"); 641 642 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { 643 ++j; 644 seq_printf(m, "\n\t%d) ", j); 645 cifs_debug_tcon(m, tcon); 646 } 647 648 spin_lock(&ses->iface_lock); 649 if (ses->iface_count) 650 seq_printf(m, "\n\n\tServer interfaces: %zu" 651 "\tLast updated: %lu seconds ago", 652 ses->iface_count, 653 (jiffies - ses->iface_last_update) / HZ); 654 655 last_iface = list_last_entry(&ses->iface_list, 656 struct cifs_server_iface, 657 iface_head); 658 iface_min_speed = last_iface->speed; 659 660 j = 0; 661 list_for_each_entry(iface, &ses->iface_list, 662 iface_head) { 663 seq_printf(m, "\n\t%d)", ++j); 664 cifs_dump_iface(m, iface); 665 666 iface_weight = iface->speed / iface_min_speed; 667 seq_printf(m, "\t\tWeight (cur,total): (%zu,%zu)" 668 "\n\t\tAllocated channels: %u\n", 669 iface->weight_fulfilled, 670 iface_weight, 671 iface->num_channels); 672 673 if (is_ses_using_iface(ses, iface)) 674 seq_puts(m, "\t\t[CONNECTED]\n"); 675 } 676 spin_unlock(&ses->iface_lock); 677 678 seq_puts(m, "\n\n\tMIDs: "); 679 spin_lock(&ses->chan_lock); 680 for (j = 0; j < ses->chan_count; j++) { 681 chan_server = ses->chans[j].server; 682 if (!chan_server) 683 continue; 684 685 if (list_empty(&chan_server->pending_mid_q)) 686 continue; 687 688 seq_printf(m, "\n\tServer ConnectionId: 0x%llx", 689 chan_server->conn_id); 690 spin_lock(&chan_server->mid_queue_lock); 691 list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) { 692 seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu", 693 mid_entry->mid_state, 694 le16_to_cpu(mid_entry->command), 695 mid_entry->pid, 696 mid_entry->callback_data, 697 mid_entry->mid); 698 } 699 spin_unlock(&chan_server->mid_queue_lock); 700 } 701 spin_unlock(&ses->chan_lock); 702 seq_puts(m, "\n--\n"); 703 } 704 if (i == 0) 705 seq_printf(m, "\n\t\t[NONE]"); 706 } 707 if (c == 0) 708 seq_printf(m, "\n\t[NONE]"); 709 710 spin_unlock(&cifs_tcp_ses_lock); 711 seq_putc(m, '\n'); 712 cifs_swn_dump(m); 713 714 /* BB add code to dump additional info such as TCP session info now */ 715 return 0; 716 } 717 718 static ssize_t cifs_stats_proc_write(struct file *file, 719 const char __user *buffer, size_t count, loff_t *ppos) 720 { 721 bool bv; 722 int rc; 723 struct TCP_Server_Info *server; 724 struct cifs_ses *ses; 725 struct cifs_tcon *tcon; 726 727 rc = kstrtobool_from_user(buffer, count, &bv); 728 if (rc == 0) { 729 #ifdef CONFIG_CIFS_STATS2 730 int i; 731 732 atomic_set(&total_buf_alloc_count, 0); 733 atomic_set(&total_small_buf_alloc_count, 0); 734 #endif /* CONFIG_CIFS_STATS2 */ 735 atomic_set(&tcpSesReconnectCount, 0); 736 atomic_set(&tconInfoReconnectCount, 0); 737 738 spin_lock(&GlobalMid_Lock); 739 GlobalMaxActiveXid = 0; 740 GlobalCurrentXid = 0; 741 spin_unlock(&GlobalMid_Lock); 742 spin_lock(&cifs_tcp_ses_lock); 743 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 744 server->max_in_flight = 0; 745 #ifdef CONFIG_CIFS_STATS2 746 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { 747 atomic_set(&server->num_cmds[i], 0); 748 atomic_set(&server->smb2slowcmd[i], 0); 749 server->time_per_cmd[i] = 0; 750 server->slowest_cmd[i] = 0; 751 server->fastest_cmd[0] = 0; 752 } 753 #endif /* CONFIG_CIFS_STATS2 */ 754 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 755 if (cifs_ses_exiting(ses)) 756 continue; 757 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { 758 atomic_set(&tcon->num_smbs_sent, 0); 759 spin_lock(&tcon->stat_lock); 760 tcon->bytes_read = 0; 761 tcon->bytes_written = 0; 762 tcon->stats_from_time = ktime_get_real_seconds(); 763 spin_unlock(&tcon->stat_lock); 764 if (server->ops->clear_stats) 765 server->ops->clear_stats(tcon); 766 } 767 } 768 } 769 spin_unlock(&cifs_tcp_ses_lock); 770 } else { 771 return rc; 772 } 773 774 return count; 775 } 776 777 static int cifs_stats_proc_show(struct seq_file *m, void *v) 778 { 779 int i; 780 #ifdef CONFIG_CIFS_STATS2 781 int j; 782 #endif /* STATS2 */ 783 struct TCP_Server_Info *server; 784 struct cifs_ses *ses; 785 struct cifs_tcon *tcon; 786 787 seq_printf(m, "Resources in use\nCIFS Session: %d\n", 788 sesInfoAllocCount.counter); 789 seq_printf(m, "Share (unique mount targets): %d\n", 790 tconInfoAllocCount.counter); 791 seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n", 792 buf_alloc_count.counter, 793 cifs_min_rcv + tcpSesAllocCount.counter); 794 seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", 795 small_buf_alloc_count.counter, cifs_min_small); 796 #ifdef CONFIG_CIFS_STATS2 797 seq_printf(m, "Total Large %d Small %d Allocations\n", 798 atomic_read(&total_buf_alloc_count), 799 atomic_read(&total_small_buf_alloc_count)); 800 #endif /* CONFIG_CIFS_STATS2 */ 801 802 seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&mid_count)); 803 seq_printf(m, 804 "\n%d session %d share reconnects\n", 805 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); 806 807 seq_printf(m, 808 "Total vfs operations: %d maximum at one time: %d\n", 809 GlobalCurrentXid, GlobalMaxActiveXid); 810 811 i = 0; 812 spin_lock(&cifs_tcp_ses_lock); 813 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 814 seq_printf(m, "\nMax requests in flight: %d", server->max_in_flight); 815 #ifdef CONFIG_CIFS_STATS2 816 seq_puts(m, "\nTotal time spent processing by command. Time "); 817 seq_printf(m, "units are jiffies (%d per second)\n", HZ); 818 seq_puts(m, " SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n"); 819 seq_puts(m, " --------\t------\t----------\t-------\t-------\n"); 820 for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) 821 seq_printf(m, " %d\t\t%d\t%llu\t\t%u\t%u\n", j, 822 atomic_read(&server->num_cmds[j]), 823 server->time_per_cmd[j], 824 server->fastest_cmd[j], 825 server->slowest_cmd[j]); 826 for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) 827 if (atomic_read(&server->smb2slowcmd[j])) { 828 spin_lock(&server->srv_lock); 829 seq_printf(m, " %d slow responses from %s for command %d\n", 830 atomic_read(&server->smb2slowcmd[j]), 831 server->hostname, j); 832 spin_unlock(&server->srv_lock); 833 } 834 #endif /* STATS2 */ 835 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 836 if (cifs_ses_exiting(ses)) 837 continue; 838 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { 839 i++; 840 seq_printf(m, "\n%d) %s", i, tcon->tree_name); 841 if (tcon->need_reconnect) 842 seq_puts(m, "\tDISCONNECTED "); 843 seq_printf(m, "\nSMBs: %d since %ptTs UTC", 844 atomic_read(&tcon->num_smbs_sent), 845 &tcon->stats_from_time); 846 if (server->ops->print_stats) 847 server->ops->print_stats(m, tcon); 848 } 849 } 850 } 851 spin_unlock(&cifs_tcp_ses_lock); 852 853 seq_putc(m, '\n'); 854 return 0; 855 } 856 857 static int cifs_stats_proc_open(struct inode *inode, struct file *file) 858 { 859 return single_open(file, cifs_stats_proc_show, NULL); 860 } 861 862 static const struct proc_ops cifs_stats_proc_ops = { 863 .proc_open = cifs_stats_proc_open, 864 .proc_read = seq_read, 865 .proc_lseek = seq_lseek, 866 .proc_release = single_release, 867 .proc_write = cifs_stats_proc_write, 868 }; 869 870 #ifdef CONFIG_CIFS_SMB_DIRECT 871 #define PROC_FILE_DEFINE(name) \ 872 static ssize_t name##_write(struct file *file, const char __user *buffer, \ 873 size_t count, loff_t *ppos) \ 874 { \ 875 int rc; \ 876 rc = kstrtoint_from_user(buffer, count, 10, &name); \ 877 if (rc) \ 878 return rc; \ 879 return count; \ 880 } \ 881 static int name##_proc_show(struct seq_file *m, void *v) \ 882 { \ 883 seq_printf(m, "%d\n", name); \ 884 return 0; \ 885 } \ 886 static int name##_open(struct inode *inode, struct file *file) \ 887 { \ 888 return single_open(file, name##_proc_show, NULL); \ 889 } \ 890 \ 891 static const struct proc_ops cifs_##name##_proc_fops = { \ 892 .proc_open = name##_open, \ 893 .proc_read = seq_read, \ 894 .proc_lseek = seq_lseek, \ 895 .proc_release = single_release, \ 896 .proc_write = name##_write, \ 897 } 898 899 PROC_FILE_DEFINE(rdma_readwrite_threshold); 900 PROC_FILE_DEFINE(smbd_max_frmr_depth); 901 PROC_FILE_DEFINE(smbd_keep_alive_interval); 902 PROC_FILE_DEFINE(smbd_max_receive_size); 903 PROC_FILE_DEFINE(smbd_max_fragmented_recv_size); 904 PROC_FILE_DEFINE(smbd_max_send_size); 905 PROC_FILE_DEFINE(smbd_send_credit_target); 906 PROC_FILE_DEFINE(smbd_receive_credit_max); 907 #endif 908 909 static struct proc_dir_entry *proc_fs_cifs; 910 static const struct proc_ops cifsFYI_proc_ops; 911 static const struct proc_ops cifs_lookup_cache_proc_ops; 912 static const struct proc_ops traceSMB_proc_ops; 913 static const struct proc_ops cifs_security_flags_proc_ops; 914 static const struct proc_ops cifs_linux_ext_proc_ops; 915 static const struct proc_ops cifs_mount_params_proc_ops; 916 917 void 918 cifs_proc_init(void) 919 { 920 proc_fs_cifs = proc_mkdir("fs/cifs", NULL); 921 if (proc_fs_cifs == NULL) 922 return; 923 924 proc_create_single("DebugData", 0, proc_fs_cifs, 925 cifs_debug_data_proc_show); 926 927 proc_create_single("open_files", 0400, proc_fs_cifs, 928 cifs_debug_files_proc_show); 929 930 proc_create_single("open_dirs", 0400, proc_fs_cifs, 931 cifs_debug_dirs_proc_show); 932 933 proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_ops); 934 proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_ops); 935 proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_ops); 936 proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs, 937 &cifs_linux_ext_proc_ops); 938 proc_create("SecurityFlags", 0644, proc_fs_cifs, 939 &cifs_security_flags_proc_ops); 940 proc_create("LookupCacheEnabled", 0644, proc_fs_cifs, 941 &cifs_lookup_cache_proc_ops); 942 943 proc_create("mount_params", 0444, proc_fs_cifs, &cifs_mount_params_proc_ops); 944 945 #ifdef CONFIG_CIFS_DFS_UPCALL 946 proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_ops); 947 #endif 948 949 #ifdef CONFIG_CIFS_SMB_DIRECT 950 proc_create("rdma_readwrite_threshold", 0644, proc_fs_cifs, 951 &cifs_rdma_readwrite_threshold_proc_fops); 952 proc_create("smbd_max_frmr_depth", 0644, proc_fs_cifs, 953 &cifs_smbd_max_frmr_depth_proc_fops); 954 proc_create("smbd_keep_alive_interval", 0644, proc_fs_cifs, 955 &cifs_smbd_keep_alive_interval_proc_fops); 956 proc_create("smbd_max_receive_size", 0644, proc_fs_cifs, 957 &cifs_smbd_max_receive_size_proc_fops); 958 proc_create("smbd_max_fragmented_recv_size", 0644, proc_fs_cifs, 959 &cifs_smbd_max_fragmented_recv_size_proc_fops); 960 proc_create("smbd_max_send_size", 0644, proc_fs_cifs, 961 &cifs_smbd_max_send_size_proc_fops); 962 proc_create("smbd_send_credit_target", 0644, proc_fs_cifs, 963 &cifs_smbd_send_credit_target_proc_fops); 964 proc_create("smbd_receive_credit_max", 0644, proc_fs_cifs, 965 &cifs_smbd_receive_credit_max_proc_fops); 966 #endif 967 } 968 969 void 970 cifs_proc_clean(void) 971 { 972 if (proc_fs_cifs == NULL) 973 return; 974 975 remove_proc_entry("DebugData", proc_fs_cifs); 976 remove_proc_entry("open_files", proc_fs_cifs); 977 remove_proc_entry("open_dirs", proc_fs_cifs); 978 remove_proc_entry("cifsFYI", proc_fs_cifs); 979 remove_proc_entry("traceSMB", proc_fs_cifs); 980 remove_proc_entry("Stats", proc_fs_cifs); 981 remove_proc_entry("SecurityFlags", proc_fs_cifs); 982 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 983 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); 984 remove_proc_entry("mount_params", proc_fs_cifs); 985 986 #ifdef CONFIG_CIFS_DFS_UPCALL 987 remove_proc_entry("dfscache", proc_fs_cifs); 988 #endif 989 #ifdef CONFIG_CIFS_SMB_DIRECT 990 remove_proc_entry("rdma_readwrite_threshold", proc_fs_cifs); 991 remove_proc_entry("smbd_max_frmr_depth", proc_fs_cifs); 992 remove_proc_entry("smbd_keep_alive_interval", proc_fs_cifs); 993 remove_proc_entry("smbd_max_receive_size", proc_fs_cifs); 994 remove_proc_entry("smbd_max_fragmented_recv_size", proc_fs_cifs); 995 remove_proc_entry("smbd_max_send_size", proc_fs_cifs); 996 remove_proc_entry("smbd_send_credit_target", proc_fs_cifs); 997 remove_proc_entry("smbd_receive_credit_max", proc_fs_cifs); 998 #endif 999 remove_proc_entry("fs/cifs", NULL); 1000 } 1001 1002 static int cifsFYI_proc_show(struct seq_file *m, void *v) 1003 { 1004 seq_printf(m, "%d\n", cifsFYI); 1005 return 0; 1006 } 1007 1008 static int cifsFYI_proc_open(struct inode *inode, struct file *file) 1009 { 1010 return single_open(file, cifsFYI_proc_show, NULL); 1011 } 1012 1013 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, 1014 size_t count, loff_t *ppos) 1015 { 1016 char c[2] = { '\0' }; 1017 bool bv; 1018 int rc; 1019 1020 rc = get_user(c[0], buffer); 1021 if (rc) 1022 return rc; 1023 if (kstrtobool(c, &bv) == 0) 1024 cifsFYI = bv; 1025 else if ((c[0] > '1') && (c[0] <= '9')) 1026 cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */ 1027 else 1028 return -EINVAL; 1029 1030 return count; 1031 } 1032 1033 static const struct proc_ops cifsFYI_proc_ops = { 1034 .proc_open = cifsFYI_proc_open, 1035 .proc_read = seq_read, 1036 .proc_lseek = seq_lseek, 1037 .proc_release = single_release, 1038 .proc_write = cifsFYI_proc_write, 1039 }; 1040 1041 static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) 1042 { 1043 seq_printf(m, "%d\n", linuxExtEnabled); 1044 return 0; 1045 } 1046 1047 static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file) 1048 { 1049 return single_open(file, cifs_linux_ext_proc_show, NULL); 1050 } 1051 1052 static ssize_t cifs_linux_ext_proc_write(struct file *file, 1053 const char __user *buffer, size_t count, loff_t *ppos) 1054 { 1055 int rc; 1056 1057 rc = kstrtobool_from_user(buffer, count, &linuxExtEnabled); 1058 if (rc) 1059 return rc; 1060 1061 return count; 1062 } 1063 1064 static const struct proc_ops cifs_linux_ext_proc_ops = { 1065 .proc_open = cifs_linux_ext_proc_open, 1066 .proc_read = seq_read, 1067 .proc_lseek = seq_lseek, 1068 .proc_release = single_release, 1069 .proc_write = cifs_linux_ext_proc_write, 1070 }; 1071 1072 static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v) 1073 { 1074 seq_printf(m, "%d\n", lookupCacheEnabled); 1075 return 0; 1076 } 1077 1078 static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file) 1079 { 1080 return single_open(file, cifs_lookup_cache_proc_show, NULL); 1081 } 1082 1083 static ssize_t cifs_lookup_cache_proc_write(struct file *file, 1084 const char __user *buffer, size_t count, loff_t *ppos) 1085 { 1086 int rc; 1087 1088 rc = kstrtobool_from_user(buffer, count, &lookupCacheEnabled); 1089 if (rc) 1090 return rc; 1091 1092 return count; 1093 } 1094 1095 static const struct proc_ops cifs_lookup_cache_proc_ops = { 1096 .proc_open = cifs_lookup_cache_proc_open, 1097 .proc_read = seq_read, 1098 .proc_lseek = seq_lseek, 1099 .proc_release = single_release, 1100 .proc_write = cifs_lookup_cache_proc_write, 1101 }; 1102 1103 static int traceSMB_proc_show(struct seq_file *m, void *v) 1104 { 1105 seq_printf(m, "%d\n", traceSMB); 1106 return 0; 1107 } 1108 1109 static int traceSMB_proc_open(struct inode *inode, struct file *file) 1110 { 1111 return single_open(file, traceSMB_proc_show, NULL); 1112 } 1113 1114 static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, 1115 size_t count, loff_t *ppos) 1116 { 1117 int rc; 1118 1119 rc = kstrtobool_from_user(buffer, count, &traceSMB); 1120 if (rc) 1121 return rc; 1122 1123 return count; 1124 } 1125 1126 static const struct proc_ops traceSMB_proc_ops = { 1127 .proc_open = traceSMB_proc_open, 1128 .proc_read = seq_read, 1129 .proc_lseek = seq_lseek, 1130 .proc_release = single_release, 1131 .proc_write = traceSMB_proc_write, 1132 }; 1133 1134 static int cifs_security_flags_proc_show(struct seq_file *m, void *v) 1135 { 1136 seq_printf(m, "0x%x\n", global_secflags); 1137 return 0; 1138 } 1139 1140 static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) 1141 { 1142 return single_open(file, cifs_security_flags_proc_show, NULL); 1143 } 1144 1145 /* 1146 * Ensure that if someone sets a MUST flag, that we disable all other MAY 1147 * flags except for the ones corresponding to the given MUST flag. If there are 1148 * multiple MUST flags, then try to prefer more secure ones. 1149 */ 1150 static void 1151 cifs_security_flags_handle_must_flags(unsigned int *flags) 1152 { 1153 unsigned int signflags = *flags & (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL); 1154 1155 if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 1156 *flags = CIFSSEC_MUST_KRB5; 1157 else if ((*flags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP) 1158 *flags = CIFSSEC_MUST_NTLMSSP; 1159 else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2) 1160 *flags = CIFSSEC_MUST_NTLMV2; 1161 1162 *flags |= signflags; 1163 } 1164 1165 static ssize_t cifs_security_flags_proc_write(struct file *file, 1166 const char __user *buffer, size_t count, loff_t *ppos) 1167 { 1168 int rc; 1169 unsigned int flags; 1170 char flags_string[12]; 1171 bool bv; 1172 1173 if ((count < 1) || (count > 11)) 1174 return -EINVAL; 1175 1176 memset(flags_string, 0, sizeof(flags_string)); 1177 1178 if (copy_from_user(flags_string, buffer, count)) 1179 return -EFAULT; 1180 1181 if (count < 3) { 1182 /* single char or single char followed by null */ 1183 if (kstrtobool(flags_string, &bv) == 0) { 1184 global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF; 1185 return count; 1186 } else if (!isdigit(flags_string[0])) { 1187 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", 1188 flags_string); 1189 return -EINVAL; 1190 } 1191 } 1192 1193 /* else we have a number */ 1194 rc = kstrtouint(flags_string, 0, &flags); 1195 if (rc) { 1196 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", 1197 flags_string); 1198 return rc; 1199 } 1200 1201 cifs_dbg(FYI, "sec flags 0x%x\n", flags); 1202 1203 if (flags == 0) { 1204 cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", flags_string); 1205 return -EINVAL; 1206 } 1207 1208 if (flags & ~CIFSSEC_MASK) { 1209 cifs_dbg(VFS, "Unsupported security flags: 0x%x\n", 1210 flags & ~CIFSSEC_MASK); 1211 return -EINVAL; 1212 } 1213 1214 cifs_security_flags_handle_must_flags(&flags); 1215 1216 /* flags look ok - update the global security flags for cifs module */ 1217 global_secflags = flags; 1218 if (global_secflags & CIFSSEC_MUST_SIGN) { 1219 /* requiring signing implies signing is allowed */ 1220 global_secflags |= CIFSSEC_MAY_SIGN; 1221 cifs_dbg(FYI, "packet signing now required\n"); 1222 } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) { 1223 cifs_dbg(FYI, "packet signing disabled\n"); 1224 } 1225 /* BB should we turn on MAY flags for other MUST options? */ 1226 return count; 1227 } 1228 1229 static const struct proc_ops cifs_security_flags_proc_ops = { 1230 .proc_open = cifs_security_flags_proc_open, 1231 .proc_read = seq_read, 1232 .proc_lseek = seq_lseek, 1233 .proc_release = single_release, 1234 .proc_write = cifs_security_flags_proc_write, 1235 }; 1236 1237 /* To make it easier to debug, can help to show mount params */ 1238 static int cifs_mount_params_proc_show(struct seq_file *m, void *v) 1239 { 1240 const struct fs_parameter_spec *p; 1241 const char *type; 1242 1243 for (p = smb3_fs_parameters; p->name; p++) { 1244 /* cannot use switch with pointers... */ 1245 if (!p->type) { 1246 if (p->flags == fs_param_neg_with_no) 1247 type = "noflag"; 1248 else 1249 type = "flag"; 1250 } else if (p->type == fs_param_is_bool) 1251 type = "bool"; 1252 else if (p->type == fs_param_is_u32) 1253 type = "u32"; 1254 else if (p->type == fs_param_is_u64) 1255 type = "u64"; 1256 else if (p->type == fs_param_is_string) 1257 type = "string"; 1258 else 1259 type = "unknown"; 1260 1261 seq_printf(m, "%s:%s\n", p->name, type); 1262 } 1263 1264 return 0; 1265 } 1266 1267 static int cifs_mount_params_proc_open(struct inode *inode, struct file *file) 1268 { 1269 return single_open(file, cifs_mount_params_proc_show, NULL); 1270 } 1271 1272 static const struct proc_ops cifs_mount_params_proc_ops = { 1273 .proc_open = cifs_mount_params_proc_open, 1274 .proc_read = seq_read, 1275 .proc_lseek = seq_lseek, 1276 .proc_release = single_release, 1277 /* No need for write for now */ 1278 /* .proc_write = cifs_mount_params_proc_write, */ 1279 }; 1280 1281 #else 1282 inline void cifs_proc_init(void) 1283 { 1284 } 1285 1286 inline void cifs_proc_clean(void) 1287 { 1288 } 1289 #endif /* PROC_FS */ 1290