cifs: clean up unaligned accesses in cifs_unicode.c

Make sure we use get/put_unaligned routines when accessing wide
character strings.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Pavel Shilovsky <piastryyy@gmail.com>
Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

authored by Jeff Layton and committed by Steve French ba2dbf30 26ec2548

+28 -23
+28 -23
fs/cifs/cifs_unicode.c
··· 44 44 int charlen, outlen = 0; 45 45 int maxwords = maxbytes / 2; 46 46 char tmp[NLS_MAX_CHARSET_SIZE]; 47 + __u16 ftmp; 47 48 48 - for (i = 0; i < maxwords && from[i]; i++) { 49 - charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp, 50 - NLS_MAX_CHARSET_SIZE); 49 + for (i = 0; i < maxwords; i++) { 50 + ftmp = get_unaligned_le16(&from[i]); 51 + if (ftmp == 0) 52 + break; 53 + 54 + charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); 51 55 if (charlen > 0) 52 56 outlen += charlen; 53 57 else ··· 62 58 } 63 59 64 60 /* 65 - * cifs_mapchar - convert a little-endian char to proper char in codepage 61 + * cifs_mapchar - convert a host-endian char to proper char in codepage 66 62 * @target - where converted character should be copied 67 - * @src_char - 2 byte little-endian source character 63 + * @src_char - 2 byte host-endian source character 68 64 * @cp - codepage to which character should be converted 69 65 * @mapchar - should character be mapped according to mapchars mount option? 70 66 * ··· 73 69 * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE). 74 70 */ 75 71 static int 76 - cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp, 72 + cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, 77 73 bool mapchar) 78 74 { 79 75 int len = 1; ··· 86 82 * build_path_from_dentry are modified, as they use slash as 87 83 * separator. 88 84 */ 89 - switch (le16_to_cpu(src_char)) { 85 + switch (src_char) { 90 86 case UNI_COLON: 91 87 *target = ':'; 92 88 break; ··· 113 109 return len; 114 110 115 111 cp_convert: 116 - len = cp->uni2char(le16_to_cpu(src_char), target, 117 - NLS_MAX_CHARSET_SIZE); 112 + len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); 118 113 if (len <= 0) { 119 114 *target = '?'; 120 115 len = 1; ··· 152 149 int nullsize = nls_nullsize(codepage); 153 150 int fromwords = fromlen / 2; 154 151 char tmp[NLS_MAX_CHARSET_SIZE]; 152 + __u16 ftmp; 155 153 156 154 /* 157 155 * because the chars can be of varying widths, we need to take care ··· 162 158 */ 163 159 safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize); 164 160 165 - for (i = 0; i < fromwords && from[i]; i++) { 161 + for (i = 0; i < fromwords; i++) { 162 + ftmp = get_unaligned_le16(&from[i]); 163 + if (ftmp == 0) 164 + break; 165 + 166 166 /* 167 167 * check to see if converting this character might make the 168 168 * conversion bleed into the null terminator 169 169 */ 170 170 if (outlen >= safelen) { 171 - charlen = cifs_mapchar(tmp, from[i], codepage, mapchar); 171 + charlen = cifs_mapchar(tmp, ftmp, codepage, mapchar); 172 172 if ((outlen + charlen) > (tolen - nullsize)) 173 173 break; 174 174 } 175 175 176 176 /* put converted char into 'to' buffer */ 177 - charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar); 177 + charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar); 178 178 outlen += charlen; 179 179 } 180 180 ··· 201 193 { 202 194 int charlen; 203 195 int i; 204 - wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */ 196 + wchar_t wchar_to; /* needed to quiet sparse */ 205 197 206 198 for (i = 0; len && *from; i++, from += charlen, len -= charlen) { 207 - 208 - /* works for 2.4.0 kernel or later */ 209 - charlen = codepage->char2uni(from, len, &wchar_to[i]); 199 + charlen = codepage->char2uni(from, len, &wchar_to); 210 200 if (charlen < 1) { 211 - cERROR(1, "strtoUCS: char2uni of %d returned %d", 212 - (int)*from, charlen); 201 + cERROR(1, "strtoUCS: char2uni of 0x%x returned %d", 202 + *from, charlen); 213 203 /* A question mark */ 214 - to[i] = cpu_to_le16(0x003f); 204 + wchar_to = 0x003f; 215 205 charlen = 1; 216 - } else 217 - to[i] = cpu_to_le16(wchar_to[i]); 218 - 206 + } 207 + put_unaligned_le16(wchar_to, &to[i]); 219 208 } 220 209 221 - to[i] = 0; 210 + put_unaligned_le16(0, &to[i]); 222 211 return i; 223 212 } 224 213