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