[PATCH RESEND 04/11] cifs: Remove cifs_backup_query_path_info() and replace it by cifs_query_path_info()
Pali Rohár <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Response handling of cifs_backup_query_path_info() function in cifs_get_fattr() is broken and can cause buffer overflows because cifs_backup_query_path_info() prepares request with different info levels but the response parser in cifs_get_fattr() always expects response structure FILE_DIRECTORY_INFO. Code which queries file/dir attributes via CIFSFindFirst() is already implemented in cifs_query_path_info() function, so extend it for backup_cred(), which is the only missing functionality compared to cifs_backup_query_path_info(). With this change the cifs_query_path_info() would do everything which is open-coded in cifs_set_fattr_ino() and cifs_backup_query_path_info() functions for SMB1. So remove that SMB1 code from cifs_set_fattr_ino() and also remove whole cifs_backup_query_path_info() function. Signed-off-by: Pali Rohár <[email protected]> --- fs/smb/client/inode.c | 97 ----------------------------------------- fs/smb/client/smb1ops.c | 7 ++- 2 files changed, 5 insertions(+), 99 deletions(-) diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 1dbcfd163ff0..6f82aa9bd033 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -1059,61 +1059,6 @@ static __u64 simple_hashstr(const char *str) return hash; } -#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY -/** - * cifs_backup_query_path_info - SMB1 fallback code to get ino - * - * Fallback code to get file metadata when we don't have access to - * full_path (EACCES) and have backup creds. - * - * @xid: transaction id used to identify original request in logs - * @tcon: information about the server share we have mounted - * @sb: the superblock stores info such as disk space available - * @full_path: name of the file we are getting the metadata for - * @resp_buf: will be set to cifs resp buf and needs to be freed with - * cifs_buf_release() when done with @data - * @data: will be set to search info result buffer - */ -static int -cifs_backup_query_path_info(int xid, - struct cifs_tcon *tcon, - struct super_block *sb, - const char *full_path, - void **resp_buf, - FILE_ALL_INFO **data) -{ - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifs_search_info info = {0}; - u16 flags; - int rc; - - *resp_buf = NULL; - info.endOfSearch = false; - if (tcon->unix_ext) - info.info_level = SMB_FIND_FILE_UNIX; - else if ((tcon->ses->capabilities & - tcon->ses->server->vals->cap_nt_find) == 0) - info.info_level = SMB_FIND_FILE_INFO_STANDARD; - else if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) - info.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; - else /* no srvino useful for fallback to some netapp */ - info.info_level = SMB_FIND_FILE_DIRECTORY_INFO; - - flags = CIFS_SEARCH_CLOSE_ALWAYS | - CIFS_SEARCH_CLOSE_AT_END | - CIFS_SEARCH_BACKUP_SEARCH; - - rc = CIFSFindFirst(xid, tcon, full_path, - cifs_sb, NULL, flags, &info, false); - if (rc) - return rc; - - *resp_buf = (void *)info.ntwrk_buf_start; - *data = (FILE_ALL_INFO *)info.srch_entries_start; - return 0; -} -#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ - static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb, struct inode **inode, const char *full_path, struct cifs_open_info_data *data, struct cifs_fattr *fattr) @@ -1328,45 +1273,6 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, cifs_create_junction_fattr(fattr, sb); rc = 0; break; - case -EACCES: -#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY - /* - * perm errors, try again with backup flags if possible - * - * For SMB2 and later the backup intent flag - * is already sent if needed on open and there - * is no path based FindFirst operation to use - * to retry with - */ - if (backup_cred(cifs_sb) && is_smb1_server(server)) { - /* for easier reading */ - FILE_ALL_INFO *fi; - FILE_DIRECTORY_INFO *fdi; - FILE_ID_FULL_DIR_INFO *si; - - rc = cifs_backup_query_path_info(xid, tcon, sb, - full_path, - &smb1_backup_rsp_buf, - &fi); - if (rc) - goto out; - - move_cifs_info_to_smb2(&data->fi, fi); - fdi = (FILE_DIRECTORY_INFO *)fi; - si = (FILE_ID_FULL_DIR_INFO *)fi; - - cifs_dir_info_to_fattr(fattr, fdi, cifs_sb); - fattr->cf_uniqueid = le64_to_cpu(si->UniqueId); - /* uniqueid set, skip get inum step */ - goto handle_mnt_opt; - } else { - /* nothing we can do, bail out */ - goto out; - } -#else - goto out; -#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ - break; default: cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc); goto out; @@ -1381,9 +1287,6 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, /* * 4. Tweak fattr based on mount options */ -#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY -handle_mnt_opt: -#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ sbflags = cifs_sb_flags(cifs_sb); /* query for SFU type info if supported and needed */ if ((fattr->cf_cifsattrs & ATTR_SYSTEM) && diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index e14ab5449943..8bacbcad8858 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -568,15 +568,18 @@ static int cifs_query_path_info(const unsigned int xid, /* * Then fallback to CIFSFindFirst() which works also with non-NT servers * but does not does not provide NumberOfLinks. + * Can be used with backup intent flag to overcome -EACCES error. */ - if ((rc == -EOPNOTSUPP || rc == -EINVAL) && + if ((rc == -EOPNOTSUPP || rc == -EINVAL || + (backup_cred(cifs_sb) && rc == -EACCES)) && !non_unicode_wildcard) { if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) search_info.info_level = SMB_FIND_FILE_INFO_STANDARD; else search_info.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO; rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb, NULL, - CIFS_SEARCH_CLOSE_ALWAYS | CIFS_SEARCH_CLOSE_AT_END, + CIFS_SEARCH_CLOSE_ALWAYS | CIFS_SEARCH_CLOSE_AT_END | + (backup_cred(cifs_sb) ? CIFS_SEARCH_BACKUP_SEARCH : 0), &search_info, false); if (rc == 0) { if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) { -- 2.20.1