reparse.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2024 Paulo Alcantara <pc@manguebit.com>
  4. */
  5. #include <linux/fs.h>
  6. #include <linux/stat.h>
  7. #include <linux/slab.h>
  8. #include "cifsglob.h"
  9. #include "smb2proto.h"
  10. #include "cifsproto.h"
  11. #include "cifs_unicode.h"
  12. #include "cifs_debug.h"
  13. #include "fs_context.h"
  14. #include "reparse.h"
  15. static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb,
  16. const unsigned int xid,
  17. const char *full_path,
  18. const char *symname,
  19. bool *directory);
  20. int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
  21. struct dentry *dentry, struct cifs_tcon *tcon,
  22. const char *full_path, const char *symname)
  23. {
  24. struct reparse_symlink_data_buffer *buf = NULL;
  25. struct cifs_open_info_data data;
  26. struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
  27. struct inode *new;
  28. struct kvec iov;
  29. __le16 *path;
  30. bool directory;
  31. char *sym, sep = CIFS_DIR_SEP(cifs_sb);
  32. u16 len, plen;
  33. int rc = 0;
  34. if (strlen(symname) > REPARSE_SYM_PATH_MAX)
  35. return -ENAMETOOLONG;
  36. sym = kstrdup(symname, GFP_KERNEL);
  37. if (!sym)
  38. return -ENOMEM;
  39. data = (struct cifs_open_info_data) {
  40. .reparse_point = true,
  41. .reparse = { .tag = IO_REPARSE_TAG_SYMLINK, },
  42. .symlink_target = sym,
  43. };
  44. convert_delimiter(sym, sep);
  45. path = cifs_convert_path_to_utf16(sym, cifs_sb);
  46. if (!path) {
  47. rc = -ENOMEM;
  48. goto out;
  49. }
  50. /*
  51. * SMB distinguish between symlink to directory and symlink to file.
  52. * They cannot be exchanged (symlink of file type which points to
  53. * directory cannot be resolved and vice-versa). Try to detect if
  54. * the symlink target could be a directory or not. When detection
  55. * fails then treat symlink as a file (non-directory) symlink.
  56. */
  57. directory = false;
  58. rc = detect_directory_symlink_target(cifs_sb, xid, full_path, symname, &directory);
  59. if (rc < 0)
  60. goto out;
  61. plen = 2 * UniStrnlen((wchar_t *)path, REPARSE_SYM_PATH_MAX);
  62. len = sizeof(*buf) + plen * 2;
  63. buf = kzalloc(len, GFP_KERNEL);
  64. if (!buf) {
  65. rc = -ENOMEM;
  66. goto out;
  67. }
  68. buf->ReparseTag = cpu_to_le32(IO_REPARSE_TAG_SYMLINK);
  69. buf->ReparseDataLength = cpu_to_le16(len - sizeof(struct reparse_data_buffer));
  70. buf->SubstituteNameOffset = cpu_to_le16(plen);
  71. buf->SubstituteNameLength = cpu_to_le16(plen);
  72. memcpy(&buf->PathBuffer[plen], path, plen);
  73. buf->PrintNameOffset = 0;
  74. buf->PrintNameLength = cpu_to_le16(plen);
  75. memcpy(buf->PathBuffer, path, plen);
  76. buf->Flags = cpu_to_le32(*symname != '/' ? SYMLINK_FLAG_RELATIVE : 0);
  77. if (*sym != sep)
  78. buf->Flags = cpu_to_le32(SYMLINK_FLAG_RELATIVE);
  79. convert_delimiter(sym, '/');
  80. iov.iov_base = buf;
  81. iov.iov_len = len;
  82. new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
  83. tcon, full_path, directory,
  84. &iov, NULL);
  85. if (!IS_ERR(new))
  86. d_instantiate(dentry, new);
  87. else
  88. rc = PTR_ERR(new);
  89. out:
  90. kfree(path);
  91. cifs_free_open_info(&data);
  92. kfree(buf);
  93. return rc;
  94. }
  95. static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb,
  96. const unsigned int xid,
  97. const char *full_path,
  98. const char *symname,
  99. bool *directory)
  100. {
  101. char sep = CIFS_DIR_SEP(cifs_sb);
  102. struct cifs_open_parms oparms;
  103. struct tcon_link *tlink;
  104. struct cifs_tcon *tcon;
  105. const char *basename;
  106. struct cifs_fid fid;
  107. char *resolved_path;
  108. int full_path_len;
  109. int basename_len;
  110. int symname_len;
  111. char *path_sep;
  112. __u32 oplock;
  113. int open_rc;
  114. /*
  115. * First do some simple check. If the original Linux symlink target ends
  116. * with slash, or last path component is dot or dot-dot then it is for
  117. * sure symlink to the directory.
  118. */
  119. basename = kbasename(symname);
  120. basename_len = strlen(basename);
  121. if (basename_len == 0 || /* symname ends with slash */
  122. (basename_len == 1 && basename[0] == '.') || /* last component is "." */
  123. (basename_len == 2 && basename[0] == '.' && basename[1] == '.')) { /* or ".." */
  124. *directory = true;
  125. return 0;
  126. }
  127. /*
  128. * For absolute symlinks it is not possible to determinate
  129. * if it should point to directory or file.
  130. */
  131. if (symname[0] == '/') {
  132. cifs_dbg(FYI,
  133. "%s: cannot determinate if the symlink target path '%s' "
  134. "is directory or not, creating '%s' as file symlink\n",
  135. __func__, symname, full_path);
  136. return 0;
  137. }
  138. /*
  139. * If it was not detected as directory yet and the symlink is relative
  140. * then try to resolve the path on the SMB server, check if the path
  141. * exists and determinate if it is a directory or not.
  142. */
  143. full_path_len = strlen(full_path);
  144. symname_len = strlen(symname);
  145. tlink = cifs_sb_tlink(cifs_sb);
  146. if (IS_ERR(tlink))
  147. return PTR_ERR(tlink);
  148. resolved_path = kzalloc(full_path_len + symname_len + 1, GFP_KERNEL);
  149. if (!resolved_path) {
  150. cifs_put_tlink(tlink);
  151. return -ENOMEM;
  152. }
  153. /*
  154. * Compose the resolved SMB symlink path from the SMB full path
  155. * and Linux target symlink path.
  156. */
  157. memcpy(resolved_path, full_path, full_path_len+1);
  158. path_sep = strrchr(resolved_path, sep);
  159. if (path_sep)
  160. path_sep++;
  161. else
  162. path_sep = resolved_path;
  163. memcpy(path_sep, symname, symname_len+1);
  164. if (sep == '\\')
  165. convert_delimiter(path_sep, sep);
  166. tcon = tlink_tcon(tlink);
  167. oparms = CIFS_OPARMS(cifs_sb, tcon, resolved_path,
  168. FILE_READ_ATTRIBUTES, FILE_OPEN, 0, ACL_NO_MODE);
  169. oparms.fid = &fid;
  170. /* Try to open as a directory (NOT_FILE) */
  171. oplock = 0;
  172. oparms.create_options = cifs_create_options(cifs_sb,
  173. CREATE_NOT_FILE | OPEN_REPARSE_POINT);
  174. open_rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
  175. if (open_rc == 0) {
  176. /* Successful open means that the target path is definitely a directory. */
  177. *directory = true;
  178. tcon->ses->server->ops->close(xid, tcon, &fid);
  179. } else if (open_rc == -ENOTDIR) {
  180. /* -ENOTDIR means that the target path is definitely a file. */
  181. *directory = false;
  182. } else if (open_rc == -ENOENT) {
  183. /* -ENOENT means that the target path does not exist. */
  184. cifs_dbg(FYI,
  185. "%s: symlink target path '%s' does not exist, "
  186. "creating '%s' as file symlink\n",
  187. __func__, symname, full_path);
  188. } else {
  189. /* Try to open as a file (NOT_DIR) */
  190. oplock = 0;
  191. oparms.create_options = cifs_create_options(cifs_sb,
  192. CREATE_NOT_DIR | OPEN_REPARSE_POINT);
  193. open_rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
  194. if (open_rc == 0) {
  195. /* Successful open means that the target path is definitely a file. */
  196. *directory = false;
  197. tcon->ses->server->ops->close(xid, tcon, &fid);
  198. } else if (open_rc == -EISDIR) {
  199. /* -EISDIR means that the target path is definitely a directory. */
  200. *directory = true;
  201. } else {
  202. /*
  203. * This code branch is called when we do not have a permission to
  204. * open the resolved_path or some other client/process denied
  205. * opening the resolved_path.
  206. *
  207. * TODO: Try to use ops->query_dir_first on the parent directory
  208. * of resolved_path, search for basename of resolved_path and
  209. * check if the ATTR_DIRECTORY is set in fi.Attributes. In some
  210. * case this could work also when opening of the path is denied.
  211. */
  212. cifs_dbg(FYI,
  213. "%s: cannot determinate if the symlink target path '%s' "
  214. "is directory or not, creating '%s' as file symlink\n",
  215. __func__, symname, full_path);
  216. }
  217. }
  218. kfree(resolved_path);
  219. cifs_put_tlink(tlink);
  220. return 0;
  221. }
  222. static int nfs_set_reparse_buf(struct reparse_posix_data *buf,
  223. mode_t mode, dev_t dev,
  224. struct kvec *iov)
  225. {
  226. u64 type;
  227. u16 len, dlen;
  228. len = sizeof(*buf);
  229. switch ((type = reparse_mode_nfs_type(mode))) {
  230. case NFS_SPECFILE_BLK:
  231. case NFS_SPECFILE_CHR:
  232. dlen = sizeof(__le64);
  233. break;
  234. case NFS_SPECFILE_FIFO:
  235. case NFS_SPECFILE_SOCK:
  236. dlen = 0;
  237. break;
  238. default:
  239. return -EOPNOTSUPP;
  240. }
  241. buf->ReparseTag = cpu_to_le32(IO_REPARSE_TAG_NFS);
  242. buf->Reserved = 0;
  243. buf->InodeType = cpu_to_le64(type);
  244. buf->ReparseDataLength = cpu_to_le16(len + dlen -
  245. sizeof(struct reparse_data_buffer));
  246. *(__le64 *)buf->DataBuffer = cpu_to_le64(((u64)MINOR(dev) << 32) |
  247. MAJOR(dev));
  248. iov->iov_base = buf;
  249. iov->iov_len = len + dlen;
  250. return 0;
  251. }
  252. static int mknod_nfs(unsigned int xid, struct inode *inode,
  253. struct dentry *dentry, struct cifs_tcon *tcon,
  254. const char *full_path, umode_t mode, dev_t dev)
  255. {
  256. struct cifs_open_info_data data;
  257. struct reparse_posix_data *p;
  258. struct inode *new;
  259. struct kvec iov;
  260. __u8 buf[sizeof(*p) + sizeof(__le64)];
  261. int rc;
  262. p = (struct reparse_posix_data *)buf;
  263. rc = nfs_set_reparse_buf(p, mode, dev, &iov);
  264. if (rc)
  265. return rc;
  266. data = (struct cifs_open_info_data) {
  267. .reparse_point = true,
  268. .reparse = { .tag = IO_REPARSE_TAG_NFS, .posix = p, },
  269. };
  270. new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
  271. tcon, full_path, false, &iov, NULL);
  272. if (!IS_ERR(new))
  273. d_instantiate(dentry, new);
  274. else
  275. rc = PTR_ERR(new);
  276. cifs_free_open_info(&data);
  277. return rc;
  278. }
  279. static int wsl_set_reparse_buf(struct reparse_data_buffer *buf,
  280. mode_t mode, struct kvec *iov)
  281. {
  282. u32 tag;
  283. switch ((tag = reparse_mode_wsl_tag(mode))) {
  284. case IO_REPARSE_TAG_LX_BLK:
  285. case IO_REPARSE_TAG_LX_CHR:
  286. case IO_REPARSE_TAG_LX_FIFO:
  287. case IO_REPARSE_TAG_AF_UNIX:
  288. break;
  289. default:
  290. return -EOPNOTSUPP;
  291. }
  292. buf->ReparseTag = cpu_to_le32(tag);
  293. buf->Reserved = 0;
  294. buf->ReparseDataLength = 0;
  295. iov->iov_base = buf;
  296. iov->iov_len = sizeof(*buf);
  297. return 0;
  298. }
  299. static struct smb2_create_ea_ctx *ea_create_context(u32 dlen, size_t *cc_len)
  300. {
  301. struct smb2_create_ea_ctx *cc;
  302. *cc_len = round_up(sizeof(*cc) + dlen, 8);
  303. cc = kzalloc(*cc_len, GFP_KERNEL);
  304. if (!cc)
  305. return ERR_PTR(-ENOMEM);
  306. cc->ctx.NameOffset = cpu_to_le16(offsetof(struct smb2_create_ea_ctx,
  307. name));
  308. cc->ctx.NameLength = cpu_to_le16(4);
  309. memcpy(cc->name, SMB2_CREATE_EA_BUFFER, strlen(SMB2_CREATE_EA_BUFFER));
  310. cc->ctx.DataOffset = cpu_to_le16(offsetof(struct smb2_create_ea_ctx, ea));
  311. cc->ctx.DataLength = cpu_to_le32(dlen);
  312. return cc;
  313. }
  314. struct wsl_xattr {
  315. const char *name;
  316. __le64 value;
  317. u16 size;
  318. u32 next;
  319. };
  320. static int wsl_set_xattrs(struct inode *inode, umode_t _mode,
  321. dev_t _dev, struct kvec *iov)
  322. {
  323. struct smb2_file_full_ea_info *ea;
  324. struct smb2_create_ea_ctx *cc;
  325. struct smb3_fs_context *ctx = CIFS_SB(inode->i_sb)->ctx;
  326. __le64 uid = cpu_to_le64(from_kuid(current_user_ns(), ctx->linux_uid));
  327. __le64 gid = cpu_to_le64(from_kgid(current_user_ns(), ctx->linux_gid));
  328. __le64 dev = cpu_to_le64(((u64)MINOR(_dev) << 32) | MAJOR(_dev));
  329. __le64 mode = cpu_to_le64(_mode);
  330. struct wsl_xattr xattrs[] = {
  331. { .name = SMB2_WSL_XATTR_UID, .value = uid, .size = SMB2_WSL_XATTR_UID_SIZE, },
  332. { .name = SMB2_WSL_XATTR_GID, .value = gid, .size = SMB2_WSL_XATTR_GID_SIZE, },
  333. { .name = SMB2_WSL_XATTR_MODE, .value = mode, .size = SMB2_WSL_XATTR_MODE_SIZE, },
  334. { .name = SMB2_WSL_XATTR_DEV, .value = dev, .size = SMB2_WSL_XATTR_DEV_SIZE, },
  335. };
  336. size_t cc_len;
  337. u32 dlen = 0, next = 0;
  338. int i, num_xattrs;
  339. u8 name_size = SMB2_WSL_XATTR_NAME_LEN + 1;
  340. memset(iov, 0, sizeof(*iov));
  341. /* Exclude $LXDEV xattr for sockets and fifos */
  342. if (S_ISSOCK(_mode) || S_ISFIFO(_mode))
  343. num_xattrs = ARRAY_SIZE(xattrs) - 1;
  344. else
  345. num_xattrs = ARRAY_SIZE(xattrs);
  346. for (i = 0; i < num_xattrs; i++) {
  347. xattrs[i].next = ALIGN(sizeof(*ea) + name_size +
  348. xattrs[i].size, 4);
  349. dlen += xattrs[i].next;
  350. }
  351. cc = ea_create_context(dlen, &cc_len);
  352. if (IS_ERR(cc))
  353. return PTR_ERR(cc);
  354. ea = &cc->ea;
  355. for (i = 0; i < num_xattrs; i++) {
  356. ea = (void *)((u8 *)ea + next);
  357. next = xattrs[i].next;
  358. ea->next_entry_offset = cpu_to_le32(next);
  359. ea->ea_name_length = name_size - 1;
  360. ea->ea_value_length = cpu_to_le16(xattrs[i].size);
  361. memcpy(ea->ea_data, xattrs[i].name, name_size);
  362. memcpy(&ea->ea_data[name_size],
  363. &xattrs[i].value, xattrs[i].size);
  364. }
  365. ea->next_entry_offset = 0;
  366. iov->iov_base = cc;
  367. iov->iov_len = cc_len;
  368. return 0;
  369. }
  370. static int mknod_wsl(unsigned int xid, struct inode *inode,
  371. struct dentry *dentry, struct cifs_tcon *tcon,
  372. const char *full_path, umode_t mode, dev_t dev)
  373. {
  374. struct cifs_open_info_data data;
  375. struct reparse_data_buffer buf;
  376. struct smb2_create_ea_ctx *cc;
  377. struct inode *new;
  378. unsigned int len;
  379. struct kvec reparse_iov, xattr_iov;
  380. int rc;
  381. rc = wsl_set_reparse_buf(&buf, mode, &reparse_iov);
  382. if (rc)
  383. return rc;
  384. rc = wsl_set_xattrs(inode, mode, dev, &xattr_iov);
  385. if (rc)
  386. return rc;
  387. data = (struct cifs_open_info_data) {
  388. .reparse_point = true,
  389. .reparse = { .tag = le32_to_cpu(buf.ReparseTag), .buf = &buf, },
  390. };
  391. cc = xattr_iov.iov_base;
  392. len = le32_to_cpu(cc->ctx.DataLength);
  393. memcpy(data.wsl.eas, &cc->ea, len);
  394. data.wsl.eas_len = len;
  395. new = smb2_get_reparse_inode(&data, inode->i_sb,
  396. xid, tcon, full_path, false,
  397. &reparse_iov, &xattr_iov);
  398. if (!IS_ERR(new))
  399. d_instantiate(dentry, new);
  400. else
  401. rc = PTR_ERR(new);
  402. cifs_free_open_info(&data);
  403. kfree(xattr_iov.iov_base);
  404. return rc;
  405. }
  406. int smb2_mknod_reparse(unsigned int xid, struct inode *inode,
  407. struct dentry *dentry, struct cifs_tcon *tcon,
  408. const char *full_path, umode_t mode, dev_t dev)
  409. {
  410. struct smb3_fs_context *ctx = CIFS_SB(inode->i_sb)->ctx;
  411. int rc = -EOPNOTSUPP;
  412. switch (ctx->reparse_type) {
  413. case CIFS_REPARSE_TYPE_NFS:
  414. rc = mknod_nfs(xid, inode, dentry, tcon, full_path, mode, dev);
  415. break;
  416. case CIFS_REPARSE_TYPE_WSL:
  417. rc = mknod_wsl(xid, inode, dentry, tcon, full_path, mode, dev);
  418. break;
  419. }
  420. return rc;
  421. }
  422. /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */
  423. static int parse_reparse_posix(struct reparse_posix_data *buf,
  424. struct cifs_sb_info *cifs_sb,
  425. struct cifs_open_info_data *data)
  426. {
  427. unsigned int len;
  428. u64 type;
  429. len = le16_to_cpu(buf->ReparseDataLength);
  430. if (len < sizeof(buf->InodeType)) {
  431. cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
  432. return -EIO;
  433. }
  434. len -= sizeof(buf->InodeType);
  435. switch ((type = le64_to_cpu(buf->InodeType))) {
  436. case NFS_SPECFILE_LNK:
  437. if (len == 0 || (len % 2)) {
  438. cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
  439. return -EIO;
  440. }
  441. /*
  442. * Check that buffer does not contain UTF-16 null codepoint
  443. * because Linux cannot process symlink with null byte.
  444. */
  445. if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
  446. cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
  447. return -EIO;
  448. }
  449. data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
  450. len, true,
  451. cifs_sb->local_nls);
  452. if (!data->symlink_target)
  453. return -ENOMEM;
  454. cifs_dbg(FYI, "%s: target path: %s\n",
  455. __func__, data->symlink_target);
  456. break;
  457. case NFS_SPECFILE_CHR:
  458. case NFS_SPECFILE_BLK:
  459. /* DataBuffer for block and char devices contains two 32-bit numbers */
  460. if (len != 8) {
  461. cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
  462. return -EIO;
  463. }
  464. break;
  465. case NFS_SPECFILE_FIFO:
  466. case NFS_SPECFILE_SOCK:
  467. /* DataBuffer for fifos and sockets is empty */
  468. if (len != 0) {
  469. cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
  470. return -EIO;
  471. }
  472. break;
  473. default:
  474. cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
  475. __func__, type);
  476. return -EOPNOTSUPP;
  477. }
  478. return 0;
  479. }
  480. int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
  481. bool unicode, bool relative,
  482. const char *full_path,
  483. struct cifs_sb_info *cifs_sb)
  484. {
  485. char sep = CIFS_DIR_SEP(cifs_sb);
  486. char *linux_target = NULL;
  487. char *smb_target = NULL;
  488. int levels;
  489. int rc;
  490. int i;
  491. smb_target = cifs_strndup_from_utf16(buf, len, unicode, cifs_sb->local_nls);
  492. if (!smb_target) {
  493. rc = -ENOMEM;
  494. goto out;
  495. }
  496. if (smb_target[0] == sep && relative) {
  497. /*
  498. * This is a relative SMB symlink from the top of the share,
  499. * which is the top level directory of the Linux mount point.
  500. * Linux does not support such relative symlinks, so convert
  501. * it to the relative symlink from the current directory.
  502. * full_path is the SMB path to the symlink (from which is
  503. * extracted current directory) and smb_target is the SMB path
  504. * where symlink points, therefore full_path must always be on
  505. * the SMB share.
  506. */
  507. int smb_target_len = strlen(smb_target)+1;
  508. levels = 0;
  509. for (i = 1; full_path[i]; i++) { /* i=1 to skip leading sep */
  510. if (full_path[i] == sep)
  511. levels++;
  512. }
  513. linux_target = kmalloc(levels*3 + smb_target_len, GFP_KERNEL);
  514. if (!linux_target) {
  515. rc = -ENOMEM;
  516. goto out;
  517. }
  518. for (i = 0; i < levels; i++) {
  519. linux_target[i*3 + 0] = '.';
  520. linux_target[i*3 + 1] = '.';
  521. linux_target[i*3 + 2] = sep;
  522. }
  523. memcpy(linux_target + levels*3, smb_target+1, smb_target_len); /* +1 to skip leading sep */
  524. } else {
  525. linux_target = smb_target;
  526. smb_target = NULL;
  527. }
  528. if (sep == '\\')
  529. convert_delimiter(linux_target, '/');
  530. rc = 0;
  531. *target = linux_target;
  532. cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, *target);
  533. out:
  534. if (rc != 0)
  535. kfree(linux_target);
  536. kfree(smb_target);
  537. return rc;
  538. }
  539. static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym,
  540. u32 plen, bool unicode,
  541. struct cifs_sb_info *cifs_sb,
  542. const char *full_path,
  543. struct cifs_open_info_data *data)
  544. {
  545. unsigned int len;
  546. unsigned int offs;
  547. /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */
  548. offs = le16_to_cpu(sym->SubstituteNameOffset);
  549. len = le16_to_cpu(sym->SubstituteNameLength);
  550. if (offs + 20 > plen || offs + len + 20 > plen) {
  551. cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
  552. return -EIO;
  553. }
  554. return smb2_parse_native_symlink(&data->symlink_target,
  555. sym->PathBuffer + offs,
  556. len,
  557. unicode,
  558. le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE,
  559. full_path,
  560. cifs_sb);
  561. }
  562. int parse_reparse_point(struct reparse_data_buffer *buf,
  563. u32 plen, struct cifs_sb_info *cifs_sb,
  564. const char *full_path,
  565. bool unicode, struct cifs_open_info_data *data)
  566. {
  567. data->reparse.buf = buf;
  568. /* See MS-FSCC 2.1.2 */
  569. switch (le32_to_cpu(buf->ReparseTag)) {
  570. case IO_REPARSE_TAG_NFS:
  571. return parse_reparse_posix((struct reparse_posix_data *)buf,
  572. cifs_sb, data);
  573. case IO_REPARSE_TAG_SYMLINK:
  574. return parse_reparse_symlink(
  575. (struct reparse_symlink_data_buffer *)buf,
  576. plen, unicode, cifs_sb, full_path, data);
  577. case IO_REPARSE_TAG_LX_SYMLINK:
  578. case IO_REPARSE_TAG_AF_UNIX:
  579. case IO_REPARSE_TAG_LX_FIFO:
  580. case IO_REPARSE_TAG_LX_CHR:
  581. case IO_REPARSE_TAG_LX_BLK:
  582. if (le16_to_cpu(buf->ReparseDataLength) != 0) {
  583. cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n",
  584. le32_to_cpu(buf->ReparseTag));
  585. return -EIO;
  586. }
  587. return 0;
  588. default:
  589. return -EOPNOTSUPP;
  590. }
  591. }
  592. int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
  593. const char *full_path,
  594. struct kvec *rsp_iov,
  595. struct cifs_open_info_data *data)
  596. {
  597. struct reparse_data_buffer *buf;
  598. struct smb2_ioctl_rsp *io = rsp_iov->iov_base;
  599. u32 plen = le32_to_cpu(io->OutputCount);
  600. buf = (struct reparse_data_buffer *)((u8 *)io +
  601. le32_to_cpu(io->OutputOffset));
  602. return parse_reparse_point(buf, plen, cifs_sb, full_path, true, data);
  603. }
  604. static bool wsl_to_fattr(struct cifs_open_info_data *data,
  605. struct cifs_sb_info *cifs_sb,
  606. u32 tag, struct cifs_fattr *fattr)
  607. {
  608. struct smb2_file_full_ea_info *ea;
  609. bool have_xattr_dev = false;
  610. u32 next = 0;
  611. switch (tag) {
  612. case IO_REPARSE_TAG_LX_SYMLINK:
  613. fattr->cf_mode |= S_IFLNK;
  614. break;
  615. case IO_REPARSE_TAG_LX_FIFO:
  616. fattr->cf_mode |= S_IFIFO;
  617. break;
  618. case IO_REPARSE_TAG_AF_UNIX:
  619. fattr->cf_mode |= S_IFSOCK;
  620. break;
  621. case IO_REPARSE_TAG_LX_CHR:
  622. fattr->cf_mode |= S_IFCHR;
  623. break;
  624. case IO_REPARSE_TAG_LX_BLK:
  625. fattr->cf_mode |= S_IFBLK;
  626. break;
  627. }
  628. if (!data->wsl.eas_len)
  629. goto out;
  630. ea = (struct smb2_file_full_ea_info *)data->wsl.eas;
  631. do {
  632. const char *name;
  633. void *v;
  634. u8 nlen;
  635. ea = (void *)((u8 *)ea + next);
  636. next = le32_to_cpu(ea->next_entry_offset);
  637. if (!le16_to_cpu(ea->ea_value_length))
  638. continue;
  639. name = ea->ea_data;
  640. nlen = ea->ea_name_length;
  641. v = (void *)((u8 *)ea->ea_data + ea->ea_name_length + 1);
  642. if (!strncmp(name, SMB2_WSL_XATTR_UID, nlen))
  643. fattr->cf_uid = wsl_make_kuid(cifs_sb, v);
  644. else if (!strncmp(name, SMB2_WSL_XATTR_GID, nlen))
  645. fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
  646. else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
  647. /* File type in reparse point tag and in xattr mode must match. */
  648. if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
  649. return false;
  650. fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
  651. } else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
  652. fattr->cf_rdev = reparse_mkdev(v);
  653. have_xattr_dev = true;
  654. }
  655. } while (next);
  656. out:
  657. /* Major and minor numbers for char and block devices are mandatory. */
  658. if (!have_xattr_dev && (tag == IO_REPARSE_TAG_LX_CHR || tag == IO_REPARSE_TAG_LX_BLK))
  659. return false;
  660. return true;
  661. }
  662. static bool posix_reparse_to_fattr(struct cifs_sb_info *cifs_sb,
  663. struct cifs_fattr *fattr,
  664. struct cifs_open_info_data *data)
  665. {
  666. struct reparse_posix_data *buf = data->reparse.posix;
  667. if (buf == NULL)
  668. return true;
  669. if (le16_to_cpu(buf->ReparseDataLength) < sizeof(buf->InodeType)) {
  670. WARN_ON_ONCE(1);
  671. return false;
  672. }
  673. switch (le64_to_cpu(buf->InodeType)) {
  674. case NFS_SPECFILE_CHR:
  675. if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8) {
  676. WARN_ON_ONCE(1);
  677. return false;
  678. }
  679. fattr->cf_mode |= S_IFCHR;
  680. fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
  681. break;
  682. case NFS_SPECFILE_BLK:
  683. if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8) {
  684. WARN_ON_ONCE(1);
  685. return false;
  686. }
  687. fattr->cf_mode |= S_IFBLK;
  688. fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
  689. break;
  690. case NFS_SPECFILE_FIFO:
  691. fattr->cf_mode |= S_IFIFO;
  692. break;
  693. case NFS_SPECFILE_SOCK:
  694. fattr->cf_mode |= S_IFSOCK;
  695. break;
  696. case NFS_SPECFILE_LNK:
  697. fattr->cf_mode |= S_IFLNK;
  698. break;
  699. default:
  700. WARN_ON_ONCE(1);
  701. return false;
  702. }
  703. return true;
  704. }
  705. bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
  706. struct cifs_fattr *fattr,
  707. struct cifs_open_info_data *data)
  708. {
  709. u32 tag = data->reparse.tag;
  710. bool ok;
  711. switch (tag) {
  712. case IO_REPARSE_TAG_INTERNAL:
  713. if (!(fattr->cf_cifsattrs & ATTR_DIRECTORY))
  714. return false;
  715. fallthrough;
  716. case IO_REPARSE_TAG_DFS:
  717. case IO_REPARSE_TAG_DFSR:
  718. case IO_REPARSE_TAG_MOUNT_POINT:
  719. /* See cifs_create_junction_fattr() */
  720. fattr->cf_mode = S_IFDIR | 0711;
  721. break;
  722. case IO_REPARSE_TAG_LX_SYMLINK:
  723. case IO_REPARSE_TAG_LX_FIFO:
  724. case IO_REPARSE_TAG_AF_UNIX:
  725. case IO_REPARSE_TAG_LX_CHR:
  726. case IO_REPARSE_TAG_LX_BLK:
  727. ok = wsl_to_fattr(data, cifs_sb, tag, fattr);
  728. if (!ok)
  729. return false;
  730. break;
  731. case IO_REPARSE_TAG_NFS:
  732. ok = posix_reparse_to_fattr(cifs_sb, fattr, data);
  733. if (!ok)
  734. return false;
  735. break;
  736. case 0: /* SMB1 symlink */
  737. case IO_REPARSE_TAG_SYMLINK:
  738. fattr->cf_mode |= S_IFLNK;
  739. break;
  740. default:
  741. return false;
  742. }
  743. fattr->cf_dtype = S_DT(fattr->cf_mode);
  744. return true;
  745. }