FAILED: patch "[PATCH] cifs: fix potential use-after-free bugs" failed to apply to 5.15-stable tree
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Possible dependencies:
7f28af9cf542 ("cifs: fix potential use-after-free bugs")0e62904836ec ("smb3: remove trivial dfs compile warning")c88f7dcd6d64 ("cifs: support nested dfs links over reconnect") bbcce3680445 ("cifs: split out dfs code from cifs_reconnect()") 43b459aa5e22 ("cifs: introduce new helper for cifs_reconnect()") 7be3248f3139 ("cifs: To match file servers, make sure the server hostname matches")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7f28af9cf542f61758b982f8304f951ca99c8f58 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <[email protected]>
Date: Fri, 12 Nov 2021 15:16:08 -0300
Subject: [PATCH] cifs: fix potential use-after-free bugs
Ensure that share and prefix variables are set to NULL after kfree() when looping through DFS targets in __tree_connect_dfs_target().
Also, get rid of @ref in __tree_connect_dfs_target() and just pass a boolean to indicate whether we're handling link targets or not.
fs/cifs/connect.c +19 -22
@@ -4141,14 +4141,13 @@ static int target_share_matches_server(struct TCP_Server_Info *server, const cha }static int __tree_connect_dfs_target (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,char *tree, -struct dfs_cache_tgt_list *tl,struct dfs_info3_param *ref) +struct cifs_sb_info *cifs_sb,char *tree,bool islink, +struct dfs_cache_tgt_list *tl) {int rc;struct TCP_Server_Info *server = tcon->ses->server;const struct smb_version_operations *ops = server->ops;struct cifs_tcon *ipc = tcon->ses->tcon_ipc; -bool islink;char *share =NULL , *prefix =NULL ;const char *tcp_host;size_t tcp_host_len;
@@ -4157,9 +4156,6 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *textract_unc_hostname (server->hostname, &tcp_host, &tcp_host_len); - islink = ref->server_type ==DFS_TYPE_LINK ; -free_dfs_info_param (ref); - tit =dfs_cache_get_tgt_iterator (tl);if (!tit) { rc = -ENOENT ;
@@ -4173,6 +4169,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *tkfree (share);kfree (prefix); + share = prefix =NULL ;/* Check if share matches with tcp ses */ rc =dfs_cache_get_tgt_share (server->current_fullpath +1 , tit, &share, &prefix);
@@ -4209,25 +4206,23 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t* newly resolved target. */ if (dfs_cache_find (xid, tcon->ses, cifs_sb->local_nls,cifs_remap (cifs_sb), target, - ref, &ntl)) { +NULL , &ntl)) { rc = ops->tree_connect (xid, tcon->ses, tree, tcon, cifs_sb->local_nls);if (rc)continue ; rc =dfs_cache_noreq_update_tgthint (server->current_fullpath +1 , tit);if (!rc) rc =cifs_update_super_prepath (cifs_sb, prefix); -break ; - } -/* Target is another dfs share */ - rc =update_server_fullpath (server, cifs_sb, target); -dfs_cache_free_tgts (tl); - -if (!rc) { - rc = -EREMOTE ; -list_replace_init (&ntl.tl_list, &tl->tl_list); }else { -dfs_cache_free_tgts (&ntl); -free_dfs_info_param (ref); +/* Target is another dfs share */ + rc =update_server_fullpath (server, cifs_sb, target); +dfs_cache_free_tgts (tl); + +if (!rc) { + rc = -EREMOTE ; +list_replace_init (&ntl.tl_list, &tl->tl_list); + }else +dfs_cache_free_tgts (&ntl); }break ; }
@@ -4240,15 +4235,15 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t }static int tree_connect_dfs_target (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,char *tree, -struct dfs_cache_tgt_list *tl,struct dfs_info3_param *ref) +struct cifs_sb_info *cifs_sb,char *tree,bool islink, +struct dfs_cache_tgt_list *tl) {int rc;int num_links =0 ;struct TCP_Server_Info *server = tcon->ses->server;do { - rc =__tree_connect_dfs_target (xid, tcon, cifs_sb, tree, tl, ref); + rc =__tree_connect_dfs_target (xid, tcon, cifs_sb, tree, islink, tl);if (!rc || rc != -EREMOTE )break ; }while (rc = -ELOOP , ++num_links <MAX_NESTED_LINKS );
@@ -4302,7 +4297,9 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru goto out; } - rc =tree_connect_dfs_target (xid, tcon, cifs_sb, tree, &tl, &ref); + rc =tree_connect_dfs_target (xid, tcon, cifs_sb, tree, ref.server_type ==DFS_TYPE_LINK , + &tl); +free_dfs_info_param (&ref); out:kfree (tree);