diff options
author | Ronnie Sahlberg <lsahlber@redhat.com> | 2019-07-06 17:45:42 -0400 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-07-07 23:37:44 -0400 |
commit | f5f111c231f56e56e186c9a61a9d22fb8bf05faa (patch) | |
tree | 8d44ba686029991546d5d23ea25a5a801961cdc1 | |
parent | ff2a09e9196e2f9d5edc60d1a68bc3d3649d035b (diff) |
cifs: refactor and clean up arguments in the reparse point parsing
Will be helpful as we improve handling of special file types.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r-- | fs/cifs/smb2ops.c | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index c4047ad7b43f..4b0b14946343 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -2383,11 +2383,6 @@ parse_reparse_posix(struct reparse_posix_data *symlink_buf, | |||
2383 | /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */ | 2383 | /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */ |
2384 | len = le16_to_cpu(symlink_buf->ReparseDataLength); | 2384 | len = le16_to_cpu(symlink_buf->ReparseDataLength); |
2385 | 2385 | ||
2386 | if (len + sizeof(struct reparse_data_buffer) > plen) { | ||
2387 | cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); | ||
2388 | return -EINVAL; | ||
2389 | } | ||
2390 | |||
2391 | if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) { | 2386 | if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) { |
2392 | cifs_dbg(VFS, "%lld not a supported symlink type\n", | 2387 | cifs_dbg(VFS, "%lld not a supported symlink type\n", |
2393 | le64_to_cpu(symlink_buf->InodeType)); | 2388 | le64_to_cpu(symlink_buf->InodeType)); |
@@ -2437,22 +2432,38 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf, | |||
2437 | } | 2432 | } |
2438 | 2433 | ||
2439 | static int | 2434 | static int |
2440 | parse_reparse_point(struct reparse_symlink_data_buffer *buf, | 2435 | parse_reparse_point(struct reparse_data_buffer *buf, |
2441 | u32 plen, char **target_path, | 2436 | u32 plen, char **target_path, |
2442 | struct cifs_sb_info *cifs_sb) | 2437 | struct cifs_sb_info *cifs_sb) |
2443 | { | 2438 | { |
2444 | /* See MS-FSCC 2.1.2 */ | 2439 | if (plen < sizeof(struct reparse_data_buffer)) { |
2445 | if (le32_to_cpu(buf->ReparseTag) == IO_REPARSE_TAG_NFS) | 2440 | cifs_dbg(VFS, "reparse buffer is too small. Must be " |
2446 | return parse_reparse_posix((struct reparse_posix_data *)buf, | 2441 | "at least 8 bytes but was %d\n", plen); |
2447 | plen, target_path, cifs_sb); | 2442 | return -EIO; |
2448 | else if (le32_to_cpu(buf->ReparseTag) == IO_REPARSE_TAG_SYMLINK) | 2443 | } |
2449 | return parse_reparse_symlink(buf, plen, target_path, | ||
2450 | cifs_sb); | ||
2451 | 2444 | ||
2452 | cifs_dbg(VFS, "srv returned invalid symlink buffer tag:%d\n", | 2445 | if (plen < le16_to_cpu(buf->ReparseDataLength) + |
2453 | le32_to_cpu(buf->ReparseTag)); | 2446 | sizeof(struct reparse_data_buffer)) { |
2447 | cifs_dbg(VFS, "srv returned invalid reparse buf " | ||
2448 | "length: %d\n", plen); | ||
2449 | return -EIO; | ||
2450 | } | ||
2454 | 2451 | ||
2455 | return -EIO; | 2452 | /* See MS-FSCC 2.1.2 */ |
2453 | switch (le32_to_cpu(buf->ReparseTag)) { | ||
2454 | case IO_REPARSE_TAG_NFS: | ||
2455 | return parse_reparse_posix( | ||
2456 | (struct reparse_posix_data *)buf, | ||
2457 | plen, target_path, cifs_sb); | ||
2458 | case IO_REPARSE_TAG_SYMLINK: | ||
2459 | return parse_reparse_symlink( | ||
2460 | (struct reparse_symlink_data_buffer *)buf, | ||
2461 | plen, target_path, cifs_sb); | ||
2462 | default: | ||
2463 | cifs_dbg(VFS, "srv returned unknown symlink buffer " | ||
2464 | "tag:0x%08x\n", le32_to_cpu(buf->ReparseTag)); | ||
2465 | return -EOPNOTSUPP; | ||
2466 | } | ||
2456 | } | 2467 | } |
2457 | 2468 | ||
2458 | #define SMB2_SYMLINK_STRUCT_SIZE \ | 2469 | #define SMB2_SYMLINK_STRUCT_SIZE \ |
@@ -2581,23 +2592,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
2581 | goto querty_exit; | 2592 | goto querty_exit; |
2582 | } | 2593 | } |
2583 | 2594 | ||
2584 | if (plen < 8) { | 2595 | rc = parse_reparse_point(reparse_buf, plen, target_path, |
2585 | cifs_dbg(VFS, "reparse buffer is too small. Must be " | 2596 | cifs_sb); |
2586 | "at least 8 bytes but was %d\n", plen); | ||
2587 | rc = -EIO; | ||
2588 | goto querty_exit; | ||
2589 | } | ||
2590 | |||
2591 | if (plen < le16_to_cpu(reparse_buf->ReparseDataLength) + 8) { | ||
2592 | cifs_dbg(VFS, "srv returned invalid reparse buf " | ||
2593 | "length: %d\n", plen); | ||
2594 | rc = -EIO; | ||
2595 | goto querty_exit; | ||
2596 | } | ||
2597 | |||
2598 | rc = parse_reparse_point( | ||
2599 | (struct reparse_symlink_data_buffer *)reparse_buf, | ||
2600 | plen, target_path, cifs_sb); | ||
2601 | goto querty_exit; | 2597 | goto querty_exit; |
2602 | } | 2598 | } |
2603 | 2599 | ||