diff options
-rw-r--r-- | fs/cifs/cifs_unicode.c | 38 | ||||
-rw-r--r-- | fs/cifs/cifs_unicode.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 55 |
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 | */ | ||
257 | char * | ||
258 | cifs_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); |
79 | int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); | 79 | int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); |
80 | int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); | 80 | int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); |
81 | char *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 | */ | ||
90 | static int | ||
91 | cifs_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 | |||
113 | cifs_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 */ |
121 | static void mark_open_files_invalid(struct cifsTconInfo *pTcon) | 86 | static 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 | ||
4027 | parse_DFS_referrals_exit: | 3996 | parse_DFS_referrals_exit: |