aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifs_unicode.c38
-rw-r--r--fs/cifs/cifs_unicode.h2
-rw-r--r--fs/cifs/cifssmb.c55
3 files changed, 52 insertions, 43 deletions
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 614512573c67..2a879cff3a40 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -243,3 +243,41 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
243 return i; 243 return i;
244} 244}
245 245
246/*
247 * cifs_strndup - copy a string from wire format to the local codepage
248 * @src - source string
249 * @maxlen - don't walk past this many bytes in the source string
250 * @is_unicode - is this a unicode string?
251 * @codepage - destination codepage
252 *
253 * Take a string given by the server, convert it to the local codepage and
254 * put it in a new buffer. Returns a pointer to the new string or NULL on
255 * error.
256 */
257char *
258cifs_strndup(const char *src, const int maxlen, const bool is_unicode,
259 const struct nls_table *codepage)
260{
261 int len;
262 char *dst;
263
264 if (is_unicode) {
265 len = cifs_ucs2_bytes((__le16 *) src, maxlen, codepage);
266 len += nls_nullsize(codepage);
267 dst = kmalloc(len, GFP_KERNEL);
268 if (!dst)
269 return NULL;
270 cifs_from_ucs2(dst, (__le16 *) src, len, maxlen, codepage,
271 false);
272 } else {
273 len = strnlen(src, maxlen);
274 len++;
275 dst = kmalloc(len, GFP_KERNEL);
276 if (!dst)
277 return NULL;
278 strlcpy(dst, src, len);
279 }
280
281 return dst;
282}
283
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 1857f5ff9337..e620f0b42201 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -78,6 +78,8 @@ int cifs_ucs2_bytes(const __le16 *from, int maxbytes,
78 const struct nls_table *codepage); 78 const struct nls_table *codepage);
79int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); 79int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
80int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); 80int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
81char *cifs_strndup(const char *src, const int maxlen, const bool is_unicode,
82 const struct nls_table *codepage);
81#endif 83#endif
82 84
83/* 85/*
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index cadacae46b82..f15848374cfa 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -81,41 +81,6 @@ static struct {
81#endif /* CONFIG_CIFS_WEAK_PW_HASH */ 81#endif /* CONFIG_CIFS_WEAK_PW_HASH */
82#endif /* CIFS_POSIX */ 82#endif /* CIFS_POSIX */
83 83
84/* Allocates buffer into dst and copies smb string from src to it.
85 * caller is responsible for freeing dst if function returned 0.
86 * returns:
87 * on success - 0
88 * on failure - errno
89 */
90static int
91cifs_strlcpy_to_host(char **dst, const char *src, const int maxlen,
92 const bool is_unicode, const struct nls_table *nls_codepage)
93{
94 int plen;
95
96 if (is_unicode) {
97 plen = UniStrnlen((wchar_t *)src, maxlen);
98 *dst = kmalloc((4 * plen) + 2, GFP_KERNEL);
99 if (!*dst)
100 goto cifs_strlcpy_to_host_ErrExit;
101 cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage);
102 (*dst)[plen] = 0;
103 (*dst)[plen+1] = 0; /* needed for Unicode */
104 } else {
105 plen = strnlen(src, maxlen);
106 *dst = kmalloc(plen + 2, GFP_KERNEL);
107 if (!*dst)
108 goto cifs_strlcpy_to_host_ErrExit;
109 strlcpy(*dst, src, plen);
110 }
111 return 0;
112
113cifs_strlcpy_to_host_ErrExit:
114 cERROR(1, ("Failed to allocate buffer for string\n"));
115 return -ENOMEM;
116}
117
118
119/* Mark as invalid, all open files on tree connections since they 84/* Mark as invalid, all open files on tree connections since they
120 were closed when session to server was lost */ 85 were closed when session to server was lost */
121static void mark_open_files_invalid(struct cifsTconInfo *pTcon) 86static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
@@ -4008,20 +3973,24 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
4008 /* copy DfsPath */ 3973 /* copy DfsPath */
4009 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset); 3974 temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
4010 max_len = data_end - temp; 3975 max_len = data_end - temp;
4011 rc = cifs_strlcpy_to_host(&(node->path_name), temp, 3976 node->path_name = cifs_strndup(temp, max_len, is_unicode,
4012 max_len, is_unicode, nls_codepage); 3977 nls_codepage);
4013 if (rc) 3978 if (IS_ERR(node->path_name)) {
3979 rc = PTR_ERR(node->path_name);
3980 node->path_name = NULL;
4014 goto parse_DFS_referrals_exit; 3981 goto parse_DFS_referrals_exit;
3982 }
4015 3983
4016 /* copy link target UNC */ 3984 /* copy link target UNC */
4017 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset); 3985 temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
4018 max_len = data_end - temp; 3986 max_len = data_end - temp;
4019 rc = cifs_strlcpy_to_host(&(node->node_name), temp, 3987 node->node_name = cifs_strndup(temp, max_len, is_unicode,
4020 max_len, is_unicode, nls_codepage); 3988 nls_codepage);
4021 if (rc) 3989 if (IS_ERR(node->node_name)) {
3990 rc = PTR_ERR(node->node_name);
3991 node->node_name = NULL;
4022 goto parse_DFS_referrals_exit; 3992 goto parse_DFS_referrals_exit;
4023 3993 }
4024 ref += le16_to_cpu(ref->Size);
4025 } 3994 }
4026 3995
4027parse_DFS_referrals_exit: 3996parse_DFS_referrals_exit: