hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/fs/cifs/misc.c
....@@ -31,6 +31,10 @@
3131 #include "nterr.h"
3232 #include "cifs_unicode.h"
3333 #include "smb2pdu.h"
34
+#include "cifsfs.h"
35
+#ifdef CONFIG_CIFS_DFS_UPCALL
36
+#include "dns_resolve.h"
37
+#endif
3438
3539 extern mempool_t *cifs_sm_req_poolp;
3640 extern mempool_t *cifs_req_poolp;
....@@ -99,31 +103,39 @@
99103 kfree(buf_to_free->serverOS);
100104 kfree(buf_to_free->serverDomain);
101105 kfree(buf_to_free->serverNOS);
102
- kzfree(buf_to_free->password);
106
+ kfree_sensitive(buf_to_free->password);
103107 kfree(buf_to_free->user_name);
104108 kfree(buf_to_free->domainName);
105
- kzfree(buf_to_free->auth_key.response);
109
+ kfree_sensitive(buf_to_free->auth_key.response);
106110 kfree(buf_to_free->iface_list);
107
- kzfree(buf_to_free);
111
+ kfree_sensitive(buf_to_free);
108112 }
109113
110114 struct cifs_tcon *
111115 tconInfoAlloc(void)
112116 {
113117 struct cifs_tcon *ret_buf;
114
- ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
115
- if (ret_buf) {
116
- atomic_inc(&tconInfoAllocCount);
117
- ret_buf->tidStatus = CifsNew;
118
- ++ret_buf->tc_count;
119
- INIT_LIST_HEAD(&ret_buf->openFileList);
120
- INIT_LIST_HEAD(&ret_buf->tcon_list);
121
- spin_lock_init(&ret_buf->open_file_lock);
122
- mutex_init(&ret_buf->crfid.fid_mutex);
123
- ret_buf->crfid.fid = kzalloc(sizeof(struct cifs_fid),
124
- GFP_KERNEL);
125
- spin_lock_init(&ret_buf->stat_lock);
118
+
119
+ ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
120
+ if (!ret_buf)
121
+ return NULL;
122
+ ret_buf->crfid.fid = kzalloc(sizeof(*ret_buf->crfid.fid), GFP_KERNEL);
123
+ if (!ret_buf->crfid.fid) {
124
+ kfree(ret_buf);
125
+ return NULL;
126126 }
127
+
128
+ atomic_inc(&tconInfoAllocCount);
129
+ ret_buf->tidStatus = CifsNew;
130
+ ++ret_buf->tc_count;
131
+ INIT_LIST_HEAD(&ret_buf->openFileList);
132
+ INIT_LIST_HEAD(&ret_buf->tcon_list);
133
+ spin_lock_init(&ret_buf->open_file_lock);
134
+ mutex_init(&ret_buf->crfid.fid_mutex);
135
+ spin_lock_init(&ret_buf->stat_lock);
136
+ atomic_set(&ret_buf->num_local_opens, 0);
137
+ atomic_set(&ret_buf->num_remote_opens, 0);
138
+
127139 return ret_buf;
128140 }
129141
....@@ -136,8 +148,11 @@
136148 }
137149 atomic_dec(&tconInfoAllocCount);
138150 kfree(buf_to_free->nativeFileSystem);
139
- kzfree(buf_to_free->password);
151
+ kfree_sensitive(buf_to_free->password);
140152 kfree(buf_to_free->crfid.fid);
153
+#ifdef CONFIG_CIFS_DFS_UPCALL
154
+ kfree(buf_to_free->dfs_path);
155
+#endif
141156 kfree(buf_to_free);
142157 }
143158
....@@ -409,7 +424,7 @@
409424
410425 if (data_offset >
411426 len - sizeof(struct file_notify_information)) {
412
- cifs_dbg(FYI, "invalid data_offset %u\n",
427
+ cifs_dbg(FYI, "Invalid data_offset %u\n",
413428 data_offset);
414429 return true;
415430 }
....@@ -437,7 +452,7 @@
437452 large dirty files cached on the client */
438453 if ((NT_STATUS_INVALID_HANDLE) ==
439454 le32_to_cpu(pSMB->hdr.Status.CifsError)) {
440
- cifs_dbg(FYI, "invalid handle on oplock break\n");
455
+ cifs_dbg(FYI, "Invalid handle on oplock break\n");
441456 return true;
442457 } else if (ERRbadfid ==
443458 le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
....@@ -511,10 +526,18 @@
511526 cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
512527 {
513528 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
529
+ struct cifs_tcon *tcon = NULL;
530
+
531
+ if (cifs_sb->master_tlink)
532
+ tcon = cifs_sb_master_tcon(cifs_sb);
533
+
514534 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
515535 cifs_sb->mnt_cifs_serverino_autodisabled = true;
516
- cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s. This server doesn't seem to support them properly. Hardlinks will not be recognized on this mount. Consider mounting with the \"noserverino\" option to silence this message.\n",
517
- cifs_sb_master_tcon(cifs_sb)->treeName);
536
+ cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n",
537
+ tcon ? tcon->treeName : "new server");
538
+ cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS)\n");
539
+ cifs_dbg(VFS, "Hardlinks will not be recognized on this mount. Consider mounting with the \"noserverino\" option to silence this message.\n");
540
+
518541 }
519542 }
520543
....@@ -741,6 +764,8 @@
741764 goto parse_DFS_referrals_exit;
742765 }
743766
767
+ node->ttl = le32_to_cpu(ref->TimeToLive);
768
+
744769 ref++;
745770 }
746771
....@@ -758,6 +783,11 @@
758783 {
759784 struct cifs_aio_ctx *ctx;
760785
786
+ /*
787
+ * Must use kzalloc to initialize ctx->bv to NULL and ctx->direct_io
788
+ * to false so that we know when we have to unreference pages within
789
+ * cifs_aio_ctx_release()
790
+ */
761791 ctx = kzalloc(sizeof(struct cifs_aio_ctx), GFP_KERNEL);
762792 if (!ctx)
763793 return NULL;
....@@ -776,7 +806,23 @@
776806 struct cifs_aio_ctx, refcount);
777807
778808 cifsFileInfo_put(ctx->cfile);
779
- kvfree(ctx->bv);
809
+
810
+ /*
811
+ * ctx->bv is only set if setup_aio_ctx_iter() was call successfuly
812
+ * which means that iov_iter_get_pages() was a success and thus that
813
+ * we have taken reference on pages.
814
+ */
815
+ if (ctx->bv) {
816
+ unsigned i;
817
+
818
+ for (i = 0; i < ctx->npages; i++) {
819
+ if (ctx->should_dirty)
820
+ set_page_dirty(ctx->bv[i].bv_page);
821
+ put_page(ctx->bv[i].bv_page);
822
+ }
823
+ kvfree(ctx->bv);
824
+ }
825
+
780826 kfree(ctx);
781827 }
782828
....@@ -797,29 +843,27 @@
797843 struct page **pages = NULL;
798844 struct bio_vec *bv = NULL;
799845
800
- if (iter->type & ITER_KVEC) {
801
- memcpy(&ctx->iter, iter, sizeof(struct iov_iter));
846
+ if (iov_iter_is_kvec(iter)) {
847
+ memcpy(&ctx->iter, iter, sizeof(*iter));
802848 ctx->len = count;
803849 iov_iter_advance(iter, count);
804850 return 0;
805851 }
806852
807
- if (max_pages * sizeof(struct bio_vec) <= CIFS_AIO_KMALLOC_LIMIT)
808
- bv = kmalloc_array(max_pages, sizeof(struct bio_vec),
809
- GFP_KERNEL);
853
+ if (array_size(max_pages, sizeof(*bv)) <= CIFS_AIO_KMALLOC_LIMIT)
854
+ bv = kmalloc_array(max_pages, sizeof(*bv), GFP_KERNEL);
810855
811856 if (!bv) {
812
- bv = vmalloc(array_size(max_pages, sizeof(struct bio_vec)));
857
+ bv = vmalloc(array_size(max_pages, sizeof(*bv)));
813858 if (!bv)
814859 return -ENOMEM;
815860 }
816861
817
- if (max_pages * sizeof(struct page *) <= CIFS_AIO_KMALLOC_LIMIT)
818
- pages = kmalloc_array(max_pages, sizeof(struct page *),
819
- GFP_KERNEL);
862
+ if (array_size(max_pages, sizeof(*pages)) <= CIFS_AIO_KMALLOC_LIMIT)
863
+ pages = kmalloc_array(max_pages, sizeof(*pages), GFP_KERNEL);
820864
821865 if (!pages) {
822
- pages = vmalloc(array_size(max_pages, sizeof(struct page *)));
866
+ pages = vmalloc(array_size(max_pages, sizeof(*pages)));
823867 if (!pages) {
824868 kvfree(bv);
825869 return -ENOMEM;
....@@ -831,7 +875,7 @@
831875 while (count && npages < max_pages) {
832876 rc = iov_iter_get_pages(iter, pages, count, max_pages, &start);
833877 if (rc < 0) {
834
- cifs_dbg(VFS, "couldn't get user pages (rc=%zd)\n", rc);
878
+ cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
835879 break;
836880 }
837881
....@@ -868,7 +912,7 @@
868912 ctx->bv = bv;
869913 ctx->len = saved_len - count;
870914 ctx->npages = npages;
871
- iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len);
915
+ iov_iter_bvec(&ctx->iter, rw, ctx->bv, npages, ctx->len);
872916 return 0;
873917 }
874918
....@@ -890,7 +934,7 @@
890934
891935 *shash = crypto_alloc_shash(name, 0, 0);
892936 if (IS_ERR(*shash)) {
893
- cifs_dbg(VFS, "could not allocate crypto %s\n", name);
937
+ cifs_dbg(VFS, "Could not allocate crypto %s\n", name);
894938 rc = PTR_ERR(*shash);
895939 *shash = NULL;
896940 *sdesc = NULL;
....@@ -907,7 +951,6 @@
907951 }
908952
909953 (*sdesc)->shash.tfm = *shash;
910
- (*sdesc)->shash.flags = 0x0;
911954 return 0;
912955 }
913956
....@@ -931,8 +974,8 @@
931974 * Input: rqst - a smb_rqst, page - a page index for rqst
932975 * Output: *len - the length for this page, *offset - the offset for this page
933976 */
934
-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
935
- unsigned int *len, unsigned int *offset)
977
+void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
978
+ unsigned int *len, unsigned int *offset)
936979 {
937980 *len = rqst->rq_pagesz;
938981 *offset = (page == 0) ? rqst->rq_offset : 0;
....@@ -942,3 +985,218 @@
942985 else if (page == 0)
943986 *len = rqst->rq_pagesz - rqst->rq_offset;
944987 }
988
+
989
+void extract_unc_hostname(const char *unc, const char **h, size_t *len)
990
+{
991
+ const char *end;
992
+
993
+ /* skip initial slashes */
994
+ while (*unc && (*unc == '\\' || *unc == '/'))
995
+ unc++;
996
+
997
+ end = unc;
998
+
999
+ while (*end && !(*end == '\\' || *end == '/'))
1000
+ end++;
1001
+
1002
+ *h = unc;
1003
+ *len = end - unc;
1004
+}
1005
+
1006
+/**
1007
+ * copy_path_name - copy src path to dst, possibly truncating
1008
+ *
1009
+ * returns number of bytes written (including trailing nul)
1010
+ */
1011
+int copy_path_name(char *dst, const char *src)
1012
+{
1013
+ int name_len;
1014
+
1015
+ /*
1016
+ * PATH_MAX includes nul, so if strlen(src) >= PATH_MAX it
1017
+ * will truncate and strlen(dst) will be PATH_MAX-1
1018
+ */
1019
+ name_len = strscpy(dst, src, PATH_MAX);
1020
+ if (WARN_ON_ONCE(name_len < 0))
1021
+ name_len = PATH_MAX-1;
1022
+
1023
+ /* we count the trailing nul */
1024
+ name_len++;
1025
+ return name_len;
1026
+}
1027
+
1028
+struct super_cb_data {
1029
+ void *data;
1030
+ struct super_block *sb;
1031
+};
1032
+
1033
+static void tcp_super_cb(struct super_block *sb, void *arg)
1034
+{
1035
+ struct super_cb_data *sd = arg;
1036
+ struct TCP_Server_Info *server = sd->data;
1037
+ struct cifs_sb_info *cifs_sb;
1038
+ struct cifs_tcon *tcon;
1039
+
1040
+ if (sd->sb)
1041
+ return;
1042
+
1043
+ cifs_sb = CIFS_SB(sb);
1044
+ tcon = cifs_sb_master_tcon(cifs_sb);
1045
+ if (tcon->ses->server == server)
1046
+ sd->sb = sb;
1047
+}
1048
+
1049
+static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void *),
1050
+ void *data)
1051
+{
1052
+ struct super_cb_data sd = {
1053
+ .data = data,
1054
+ .sb = NULL,
1055
+ };
1056
+ struct file_system_type **fs_type = (struct file_system_type *[]) {
1057
+ &cifs_fs_type, &smb3_fs_type, NULL,
1058
+ };
1059
+
1060
+ for (; *fs_type; fs_type++) {
1061
+ iterate_supers_type(*fs_type, f, &sd);
1062
+ if (sd.sb) {
1063
+ /*
1064
+ * Grab an active reference in order to prevent automounts (DFS links)
1065
+ * of expiring and then freeing up our cifs superblock pointer while
1066
+ * we're doing failover.
1067
+ */
1068
+ cifs_sb_active(sd.sb);
1069
+ return sd.sb;
1070
+ }
1071
+ }
1072
+ return ERR_PTR(-EINVAL);
1073
+}
1074
+
1075
+static void __cifs_put_super(struct super_block *sb)
1076
+{
1077
+ if (!IS_ERR_OR_NULL(sb))
1078
+ cifs_sb_deactive(sb);
1079
+}
1080
+
1081
+struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server)
1082
+{
1083
+ return __cifs_get_super(tcp_super_cb, server);
1084
+}
1085
+
1086
+void cifs_put_tcp_super(struct super_block *sb)
1087
+{
1088
+ __cifs_put_super(sb);
1089
+}
1090
+
1091
+#ifdef CONFIG_CIFS_DFS_UPCALL
1092
+int match_target_ip(struct TCP_Server_Info *server,
1093
+ const char *share, size_t share_len,
1094
+ bool *result)
1095
+{
1096
+ int rc;
1097
+ char *target, *tip = NULL;
1098
+ struct sockaddr tipaddr;
1099
+
1100
+ *result = false;
1101
+
1102
+ target = kzalloc(share_len + 3, GFP_KERNEL);
1103
+ if (!target) {
1104
+ rc = -ENOMEM;
1105
+ goto out;
1106
+ }
1107
+
1108
+ scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share);
1109
+
1110
+ cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2);
1111
+
1112
+ rc = dns_resolve_server_name_to_ip(target, &tip);
1113
+ if (rc < 0)
1114
+ goto out;
1115
+
1116
+ cifs_dbg(FYI, "%s: target ip: %s\n", __func__, tip);
1117
+
1118
+ if (!cifs_convert_address(&tipaddr, tip, strlen(tip))) {
1119
+ cifs_dbg(VFS, "%s: failed to convert target ip address\n",
1120
+ __func__);
1121
+ rc = -EINVAL;
1122
+ goto out;
1123
+ }
1124
+
1125
+ *result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr,
1126
+ &tipaddr);
1127
+ cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
1128
+ rc = 0;
1129
+
1130
+out:
1131
+ kfree(target);
1132
+ kfree(tip);
1133
+
1134
+ return rc;
1135
+}
1136
+
1137
+static void tcon_super_cb(struct super_block *sb, void *arg)
1138
+{
1139
+ struct super_cb_data *sd = arg;
1140
+ struct cifs_tcon *tcon = sd->data;
1141
+ struct cifs_sb_info *cifs_sb;
1142
+
1143
+ if (sd->sb)
1144
+ return;
1145
+
1146
+ cifs_sb = CIFS_SB(sb);
1147
+ if (tcon->dfs_path && cifs_sb->origin_fullpath &&
1148
+ !strcasecmp(tcon->dfs_path, cifs_sb->origin_fullpath))
1149
+ sd->sb = sb;
1150
+}
1151
+
1152
+static inline struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon)
1153
+{
1154
+ return __cifs_get_super(tcon_super_cb, tcon);
1155
+}
1156
+
1157
+static inline void cifs_put_tcon_super(struct super_block *sb)
1158
+{
1159
+ __cifs_put_super(sb);
1160
+}
1161
+#else
1162
+static inline struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon)
1163
+{
1164
+ return ERR_PTR(-EOPNOTSUPP);
1165
+}
1166
+
1167
+static inline void cifs_put_tcon_super(struct super_block *sb)
1168
+{
1169
+}
1170
+#endif
1171
+
1172
+int update_super_prepath(struct cifs_tcon *tcon, char *prefix)
1173
+{
1174
+ struct super_block *sb;
1175
+ struct cifs_sb_info *cifs_sb;
1176
+ int rc = 0;
1177
+
1178
+ sb = cifs_get_tcon_super(tcon);
1179
+ if (IS_ERR(sb))
1180
+ return PTR_ERR(sb);
1181
+
1182
+ cifs_sb = CIFS_SB(sb);
1183
+
1184
+ kfree(cifs_sb->prepath);
1185
+
1186
+ if (prefix && *prefix) {
1187
+ cifs_sb->prepath = kstrndup(prefix, strlen(prefix), GFP_ATOMIC);
1188
+ if (!cifs_sb->prepath) {
1189
+ rc = -ENOMEM;
1190
+ goto out;
1191
+ }
1192
+
1193
+ convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
1194
+ } else
1195
+ cifs_sb->prepath = NULL;
1196
+
1197
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
1198
+
1199
+out:
1200
+ cifs_put_tcon_super(sb);
1201
+ return rc;
1202
+}