1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2008 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * 7 */ 8 #include <linux/fs.h> 9 #include <linux/stat.h> 10 #include <linux/slab.h> 11 #include <linux/namei.h> 12 #include "cifsfs.h" 13 #include "cifspdu.h" 14 #include "cifsglob.h" 15 #include "cifsproto.h" 16 #include "cifs_debug.h" 17 #include "cifs_fs_sb.h" 18 #include "cifs_unicode.h" 19 #include "smb2proto.h" 20 #include "cifs_ioctl.h" 21 #include "fs_context.h" 22 #include "reparse.h" 23 24 /* 25 * M-F Symlink Functions - Begin 26 */ 27 28 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 29 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) 30 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1)) 31 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024) 32 #define CIFS_MF_SYMLINK_FILE_SIZE \ 33 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN) 34 35 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n" 36 #define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n" 37 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash 38 39 static int 40 symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) 41 { 42 int rc; 43 struct shash_desc *md5 = NULL; 44 45 rc = cifs_alloc_hash("md5", &md5); 46 if (rc) 47 return rc; 48 49 rc = crypto_shash_digest(md5, link_str, link_len, md5_hash); 50 if (rc) 51 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); 52 cifs_free_hash(&md5); 53 return rc; 54 } 55 56 static int 57 parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len, 58 char **_link_str) 59 { 60 int rc; 61 unsigned int link_len; 62 const char *md5_str1; 63 const char *link_str; 64 u8 md5_hash[16]; 65 char md5_str2[34]; 66 67 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 68 return -EINVAL; 69 70 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET]; 71 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET]; 72 73 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len); 74 if (rc != 1) 75 return -EINVAL; 76 77 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 78 return -EINVAL; 79 80 rc = symlink_hash(link_len, link_str, md5_hash); 81 if (rc) { 82 cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc); 83 return rc; 84 } 85 86 scnprintf(md5_str2, sizeof(md5_str2), 87 CIFS_MF_SYMLINK_MD5_FORMAT, 88 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 89 90 if (strncmp(md5_str1, md5_str2, 17) != 0) 91 return -EINVAL; 92 93 if (_link_str) { 94 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL); 95 if (!*_link_str) 96 return -ENOMEM; 97 } 98 99 *_link_len = link_len; 100 return 0; 101 } 102 103 static int 104 format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) 105 { 106 int rc; 107 unsigned int link_len; 108 unsigned int ofs; 109 u8 md5_hash[16]; 110 111 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 112 return -EINVAL; 113 114 link_len = strlen(link_str); 115 116 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 117 return -ENAMETOOLONG; 118 119 rc = symlink_hash(link_len, link_str, md5_hash); 120 if (rc) { 121 cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc); 122 return rc; 123 } 124 125 scnprintf(buf, buf_len, 126 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, 127 link_len, 128 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 129 130 ofs = CIFS_MF_SYMLINK_LINK_OFFSET; 131 memcpy(buf + ofs, link_str, link_len); 132 133 ofs += link_len; 134 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 135 buf[ofs] = '\n'; 136 ofs++; 137 } 138 139 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 140 buf[ofs] = ' '; 141 ofs++; 142 } 143 144 return 0; 145 } 146 147 bool 148 couldbe_mf_symlink(const struct cifs_fattr *fattr) 149 { 150 if (!S_ISREG(fattr->cf_mode)) 151 /* it's not a symlink */ 152 return false; 153 154 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE) 155 /* it's not a symlink */ 156 return false; 157 158 return true; 159 } 160 161 static int 162 create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, 163 struct cifs_sb_info *cifs_sb, const char *fromName, 164 const char *toName) 165 { 166 int rc; 167 u8 *buf; 168 unsigned int bytes_written = 0; 169 170 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 171 if (!buf) 172 return -ENOMEM; 173 174 rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); 175 if (rc) 176 goto out; 177 178 if (tcon->ses->server->ops->create_mf_symlink) 179 rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon, 180 cifs_sb, fromName, buf, &bytes_written); 181 else 182 rc = -EOPNOTSUPP; 183 184 if (rc) 185 goto out; 186 187 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) 188 rc = -EIO; 189 out: 190 kfree(buf); 191 return rc; 192 } 193 194 int 195 check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 196 struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 197 const unsigned char *path) 198 { 199 int rc; 200 u8 *buf = NULL; 201 unsigned int link_len = 0; 202 unsigned int bytes_read = 0; 203 char *symlink = NULL; 204 205 if (!couldbe_mf_symlink(fattr)) 206 /* it's not a symlink */ 207 return 0; 208 209 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 210 if (!buf) 211 return -ENOMEM; 212 213 if (tcon->ses->server->ops->query_mf_symlink) 214 rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, 215 cifs_sb, path, buf, &bytes_read); 216 else 217 rc = -ENOSYS; 218 219 if (rc) 220 goto out; 221 222 if (bytes_read == 0) /* not a symlink */ 223 goto out; 224 225 rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink); 226 if (rc == -EINVAL) { 227 /* it's not a symlink */ 228 rc = 0; 229 goto out; 230 } 231 232 if (rc != 0) 233 goto out; 234 235 /* it is a symlink */ 236 fattr->cf_eof = link_len; 237 fattr->cf_mode &= ~S_IFMT; 238 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; 239 fattr->cf_dtype = DT_LNK; 240 fattr->cf_symlink_target = symlink; 241 out: 242 kfree(buf); 243 return rc; 244 } 245 246 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 247 /* 248 * SMB 1.0 Protocol specific functions 249 */ 250 251 int 252 cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 253 struct cifs_sb_info *cifs_sb, const unsigned char *path, 254 char *pbuf, unsigned int *pbytes_read) 255 { 256 int rc; 257 int oplock = 0; 258 struct cifs_fid fid; 259 struct cifs_open_parms oparms; 260 struct cifs_io_parms io_parms = {0}; 261 int buf_type = CIFS_NO_BUFFER; 262 struct cifs_open_info_data query_data; 263 264 oparms = (struct cifs_open_parms) { 265 .tcon = tcon, 266 .cifs_sb = cifs_sb, 267 .desired_access = GENERIC_READ, 268 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 269 .disposition = FILE_OPEN, 270 .path = path, 271 .fid = &fid, 272 }; 273 274 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &query_data); 275 if (rc) 276 return rc; 277 278 if (query_data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { 279 rc = -ENOENT; 280 /* it's not a symlink */ 281 goto out; 282 } 283 284 io_parms.netfid = fid.netfid; 285 io_parms.pid = current->tgid; 286 io_parms.tcon = tcon; 287 io_parms.offset = 0; 288 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 289 290 rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type); 291 out: 292 CIFSSMBClose(xid, tcon, fid.netfid); 293 return rc; 294 } 295 296 int 297 cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 298 struct cifs_sb_info *cifs_sb, const unsigned char *path, 299 char *pbuf, unsigned int *pbytes_written) 300 { 301 int rc; 302 int oplock = 0; 303 struct cifs_fid fid; 304 struct cifs_open_parms oparms; 305 struct cifs_io_parms io_parms = {0}; 306 307 oparms = (struct cifs_open_parms) { 308 .tcon = tcon, 309 .cifs_sb = cifs_sb, 310 .desired_access = GENERIC_WRITE, 311 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 312 .disposition = FILE_CREATE, 313 .path = path, 314 .fid = &fid, 315 }; 316 317 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); 318 if (rc) 319 return rc; 320 321 io_parms.netfid = fid.netfid; 322 io_parms.pid = current->tgid; 323 io_parms.tcon = tcon; 324 io_parms.offset = 0; 325 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 326 327 rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf); 328 CIFSSMBClose(xid, tcon, fid.netfid); 329 return rc; 330 } 331 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 332 333 /* 334 * SMB 2.1/SMB3 Protocol specific functions 335 */ 336 int 337 smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 338 struct cifs_sb_info *cifs_sb, const unsigned char *path, 339 char *pbuf, unsigned int *pbytes_read) 340 { 341 int rc; 342 struct cifs_fid fid; 343 struct cifs_open_parms oparms; 344 struct cifs_io_parms io_parms = {0}; 345 int buf_type = CIFS_NO_BUFFER; 346 __le16 *utf16_path; 347 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 348 struct smb2_file_all_info *pfile_info = NULL; 349 350 oparms = (struct cifs_open_parms) { 351 .tcon = tcon, 352 .cifs_sb = cifs_sb, 353 .path = path, 354 .desired_access = GENERIC_READ, 355 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 356 .disposition = FILE_OPEN, 357 .fid = &fid, 358 }; 359 360 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 361 if (utf16_path == NULL) 362 return -ENOMEM; 363 364 pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, 365 GFP_KERNEL); 366 367 if (pfile_info == NULL) { 368 kfree(utf16_path); 369 return -ENOMEM; 370 } 371 372 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL, 373 NULL, NULL); 374 if (rc) 375 goto qmf_out_open_fail; 376 377 if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { 378 /* it's not a symlink */ 379 rc = -ENOENT; /* Is there a better rc to return? */ 380 goto qmf_out; 381 } 382 383 io_parms.netfid = fid.netfid; 384 io_parms.pid = current->tgid; 385 io_parms.tcon = tcon; 386 io_parms.offset = 0; 387 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 388 io_parms.persistent_fid = fid.persistent_fid; 389 io_parms.volatile_fid = fid.volatile_fid; 390 rc = SMB2_read(xid, &io_parms, pbytes_read, &pbuf, &buf_type); 391 qmf_out: 392 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 393 qmf_out_open_fail: 394 kfree(utf16_path); 395 kfree(pfile_info); 396 return rc; 397 } 398 399 int 400 smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 401 struct cifs_sb_info *cifs_sb, const unsigned char *path, 402 char *pbuf, unsigned int *pbytes_written) 403 { 404 int rc; 405 struct cifs_fid fid; 406 struct cifs_open_parms oparms; 407 struct cifs_io_parms io_parms = {0}; 408 __le16 *utf16_path; 409 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 410 struct kvec iov[2]; 411 412 cifs_dbg(FYI, "%s: path: %s\n", __func__, path); 413 414 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 415 if (!utf16_path) 416 return -ENOMEM; 417 418 oparms = (struct cifs_open_parms) { 419 .tcon = tcon, 420 .cifs_sb = cifs_sb, 421 .path = path, 422 .desired_access = GENERIC_WRITE, 423 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 424 .disposition = FILE_CREATE, 425 .fid = &fid, 426 .mode = 0644, 427 }; 428 429 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, 430 NULL, NULL); 431 if (rc) { 432 kfree(utf16_path); 433 return rc; 434 } 435 436 io_parms.netfid = fid.netfid; 437 io_parms.pid = current->tgid; 438 io_parms.tcon = tcon; 439 io_parms.offset = 0; 440 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 441 io_parms.persistent_fid = fid.persistent_fid; 442 io_parms.volatile_fid = fid.volatile_fid; 443 444 /* iov[0] is reserved for smb header */ 445 iov[1].iov_base = pbuf; 446 iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE; 447 448 rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1); 449 450 /* Make sure we wrote all of the symlink data */ 451 if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE)) 452 rc = -EIO; 453 454 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 455 456 kfree(utf16_path); 457 return rc; 458 } 459 460 /* 461 * M-F Symlink Functions - End 462 */ 463 464 int 465 cifs_hardlink(struct dentry *old_file, struct inode *inode, 466 struct dentry *direntry) 467 { 468 int rc = -EACCES; 469 unsigned int xid; 470 const char *from_name, *to_name; 471 void *page1, *page2; 472 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 473 struct tcon_link *tlink; 474 struct cifs_tcon *tcon; 475 struct TCP_Server_Info *server; 476 struct cifsInodeInfo *cifsInode; 477 478 if (unlikely(cifs_forced_shutdown(cifs_sb))) 479 return -EIO; 480 481 tlink = cifs_sb_tlink(cifs_sb); 482 if (IS_ERR(tlink)) 483 return PTR_ERR(tlink); 484 tcon = tlink_tcon(tlink); 485 486 xid = get_xid(); 487 page1 = alloc_dentry_path(); 488 page2 = alloc_dentry_path(); 489 490 from_name = build_path_from_dentry(old_file, page1); 491 if (IS_ERR(from_name)) { 492 rc = PTR_ERR(from_name); 493 goto cifs_hl_exit; 494 } 495 to_name = build_path_from_dentry(direntry, page2); 496 if (IS_ERR(to_name)) { 497 rc = PTR_ERR(to_name); 498 goto cifs_hl_exit; 499 } 500 501 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 502 if (tcon->unix_ext) 503 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name, 504 cifs_sb->local_nls, 505 cifs_remap(cifs_sb)); 506 else { 507 #else 508 { 509 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 510 server = tcon->ses->server; 511 if (!server->ops->create_hardlink) { 512 rc = -ENOSYS; 513 goto cifs_hl_exit; 514 } 515 rc = server->ops->create_hardlink(xid, tcon, old_file, 516 from_name, to_name, cifs_sb); 517 if ((rc == -EIO) || (rc == -EINVAL)) 518 rc = -EOPNOTSUPP; 519 } 520 521 d_drop(direntry); /* force new lookup from server of target */ 522 523 /* 524 * if source file is cached (oplocked) revalidate will not go to server 525 * until the file is closed or oplock broken so update nlinks locally 526 */ 527 if (d_really_is_positive(old_file)) { 528 cifsInode = CIFS_I(d_inode(old_file)); 529 if (rc == 0) { 530 spin_lock(&d_inode(old_file)->i_lock); 531 inc_nlink(d_inode(old_file)); 532 spin_unlock(&d_inode(old_file)->i_lock); 533 534 /* 535 * parent dir timestamps will update from srv within a 536 * second, would it really be worth it to set the parent 537 * dir cifs inode time to zero to force revalidate 538 * (faster) for it too? 539 */ 540 } 541 /* 542 * if not oplocked will force revalidate to get info on source 543 * file from srv. Note Samba server prior to 4.2 has bug - 544 * not updating src file ctime on hardlinks but Windows servers 545 * handle it properly 546 */ 547 cifsInode->time = 0; 548 549 /* 550 * Will update parent dir timestamps from srv within a second. 551 * Would it really be worth it to set the parent dir (cifs 552 * inode) time field to zero to force revalidate on parent 553 * directory faster ie 554 * 555 * CIFS_I(inode)->time = 0; 556 */ 557 } 558 559 cifs_hl_exit: 560 free_dentry_path(page1); 561 free_dentry_path(page2); 562 free_xid(xid); 563 cifs_put_tlink(tlink); 564 return rc; 565 } 566 567 int 568 cifs_symlink(struct mnt_idmap *idmap, struct inode *inode, 569 struct dentry *direntry, const char *symname) 570 { 571 int rc = -EOPNOTSUPP; 572 unsigned int xid; 573 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 574 struct tcon_link *tlink; 575 struct cifs_tcon *pTcon; 576 const char *full_path; 577 void *page; 578 struct inode *newinode = NULL; 579 580 if (unlikely(cifs_forced_shutdown(cifs_sb))) 581 return -EIO; 582 583 page = alloc_dentry_path(); 584 if (!page) 585 return -ENOMEM; 586 587 xid = get_xid(); 588 589 tlink = cifs_sb_tlink(cifs_sb); 590 if (IS_ERR(tlink)) { 591 rc = PTR_ERR(tlink); 592 /* BB could be clearer if skipped put_tlink on error here, but harmless */ 593 goto symlink_exit; 594 } 595 pTcon = tlink_tcon(tlink); 596 597 full_path = build_path_from_dentry(direntry, page); 598 if (IS_ERR(full_path)) { 599 rc = PTR_ERR(full_path); 600 goto symlink_exit; 601 } 602 603 cifs_dbg(FYI, "Full path: %s\n", full_path); 604 cifs_dbg(FYI, "symname is %s\n", symname); 605 606 /* BB what if DFS and this volume is on different share? BB */ 607 rc = -EOPNOTSUPP; 608 switch (cifs_symlink_type(cifs_sb)) { 609 case CIFS_SYMLINK_TYPE_UNIX: 610 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 611 if (pTcon->unix_ext) { 612 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, 613 symname, 614 cifs_sb->local_nls, 615 cifs_remap(cifs_sb)); 616 } 617 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 618 break; 619 620 case CIFS_SYMLINK_TYPE_MFSYMLINKS: 621 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { 622 rc = create_mf_symlink(xid, pTcon, cifs_sb, 623 full_path, symname); 624 } 625 break; 626 627 case CIFS_SYMLINK_TYPE_SFU: 628 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 629 rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon, 630 full_path, S_IFLNK, 631 0, symname); 632 } 633 break; 634 635 case CIFS_SYMLINK_TYPE_NATIVE: 636 case CIFS_SYMLINK_TYPE_NFS: 637 case CIFS_SYMLINK_TYPE_WSL: 638 if (CIFS_REPARSE_SUPPORT(pTcon)) { 639 rc = create_reparse_symlink(xid, inode, direntry, pTcon, 640 full_path, symname); 641 goto symlink_exit; 642 } 643 break; 644 default: 645 break; 646 } 647 648 if (rc == 0) { 649 if (pTcon->posix_extensions) { 650 rc = smb311_posix_get_inode_info(&newinode, full_path, 651 NULL, inode->i_sb, xid); 652 } else if (pTcon->unix_ext) { 653 rc = cifs_get_inode_info_unix(&newinode, full_path, 654 inode->i_sb, xid); 655 } else { 656 rc = cifs_get_inode_info(&newinode, full_path, NULL, 657 inode->i_sb, xid, NULL); 658 } 659 660 if (rc != 0) { 661 cifs_dbg(FYI, "Create symlink ok, getinodeinfo fail rc = %d\n", 662 rc); 663 } else { 664 d_instantiate(direntry, newinode); 665 } 666 } 667 symlink_exit: 668 free_dentry_path(page); 669 cifs_put_tlink(tlink); 670 free_xid(xid); 671 return rc; 672 } 673