Re: [PATCH 4/5] cifs: clean up unaligned accesses in cifs_unicode.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jan 19, 2011 at 9:58 AM, Shirish Pargaonkar
<shirishpargaonkar@xxxxxxxxx> wrote:
> On Tue, Jan 18, 2011 at 2:33 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:
>> Make sure we use get/put_unaligned routines when accessing wide
>> character strings.
>>
>> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
>> ---
>>  fs/cifs/cifs_unicode.c |   49 ++++++++++++++++++++++++++---------------------
>>  1 files changed, 27 insertions(+), 22 deletions(-)
>>
>> diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
>> index 430f510..8134443 100644
>> --- a/fs/cifs/cifs_unicode.c
>> +++ b/fs/cifs/cifs_unicode.c
>> @@ -44,10 +44,14 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
>>        int charlen, outlen = 0;
>>        int maxwords = maxbytes / 2;
>>        char tmp[NLS_MAX_CHARSET_SIZE];
>> +       __u16 ftmp;
>>
>> -       for (i = 0; i < maxwords && from[i]; i++) {
>> -               charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,
>> -                                            NLS_MAX_CHARSET_SIZE);
>> +       for (i = 0; i < maxwords; i++) {
>> +               ftmp = get_unaligned_le16(&from[i]);
>> +               if (ftmp == 0)
>> +                       break;
>> +
>> +               charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE);
>>                if (charlen > 0)
>>                        outlen += charlen;
>>                else
>> @@ -60,7 +64,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
>>  /*
>>  * cifs_mapchar - convert a little-endian char to proper char in codepage
>
> I think this wording is now incorrect since src_char is not le anymore.
>
>>  * @target - where converted character should be copied
>> - * @src_char - 2 byte little-endian source character
>> + * @src_char - 2 byte host-endian source character
>>  * @cp - codepage to which character should be converted
>>  * @mapchar - should character be mapped according to mapchars mount option?
>>  *
>> @@ -69,7 +73,7 @@ cifs_ucs2_bytes(const __le16 *from, int maxbytes,
>>  * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
>>  */
>>  static int
>> -cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
>> +cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
>>             bool mapchar)
>>  {
>>        int len = 1;
>> @@ -82,7 +86,7 @@ cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,
>>         *     build_path_from_dentry are modified, as they use slash as
>>         *     separator.
>>         */
>> -       switch (le16_to_cpu(src_char)) {
>> +       switch (src_char) {
>>        case UNI_COLON:
>>                *target = ':';
>>                break;
>> @@ -109,8 +113,7 @@ out:
>>        return len;
>>
>>  cp_convert:
>> -       len = cp->uni2char(le16_to_cpu(src_char), target,
>> -                          NLS_MAX_CHARSET_SIZE);
>> +       len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE);
>>        if (len <= 0) {
>>                *target = '?';
>>                len = 1;
>> @@ -149,6 +152,7 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
>>        int nullsize = nls_nullsize(codepage);
>>        int fromwords = fromlen / 2;
>>        char tmp[NLS_MAX_CHARSET_SIZE];
>> +       __u16 ftmp;
>>
>>        /*
>>         * because the chars can be of varying widths, we need to take care
>> @@ -158,19 +162,23 @@ cifs_from_ucs2(char *to, const __le16 *from, int tolen, int fromlen,
>>         */
>>        safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
>>
>> -       for (i = 0; i < fromwords && from[i]; i++) {
>> +       for (i = 0; i < fromwords; i++) {
>> +               ftmp = get_unaligned_le16(&from[i]);
>> +               if (ftmp == 0)
>> +                       break;
>> +
>
> Can the contents of from[i] be 0 so ftmp is 0 but we did
> not want to break out until fromwords?
>

Basically, why_does/what_it_means get_unaligned_le16()
returning 0 warrants breaking out of the loop!

>>                /*
>>                 * check to see if converting this character might make the
>>                 * conversion bleed into the null terminator
>>                 */
>>                if (outlen >= safelen) {
>> -                       charlen = cifs_mapchar(tmp, from[i], codepage, mapchar);
>> +                       charlen = cifs_mapchar(tmp, ftmp, codepage, mapchar);
>>                        if ((outlen + charlen) > (tolen - nullsize))
>>                                break;
>>                }
>>
>>                /* put converted char into 'to' buffer */
>> -               charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar);
>> +               charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar);
>>                outlen += charlen;
>>        }
>>
>> @@ -193,24 +201,21 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
>>  {
>>        int charlen;
>>        int i;
>> -       wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */
>> +       wchar_t wchar_to; /* needed to quiet sparse */
>>
>>        for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
>> -
>> -               /* works for 2.4.0 kernel or later */
>> -               charlen = codepage->char2uni(from, len, &wchar_to[i]);
>> +               charlen = codepage->char2uni(from, len, &wchar_to);
>>                if (charlen < 1) {
>> -                       cERROR(1, "strtoUCS: char2uni of %d returned %d",
>> -                               (int)*from, charlen);
>> +                       cERROR(1, "strtoUCS: char2uni of 0x%x returned %d",
>> +                               *from, charlen);
>>                        /* A question mark */
>> -                       to[i] = cpu_to_le16(0x003f);
>> +                       wchar_to = 0x003f;
>>                        charlen = 1;
>> -               } else
>> -                       to[i] = cpu_to_le16(wchar_to[i]);
>> -
>> +               }
>> +               put_unaligned_le16(wchar_to, &to[i]);
>>        }
>>
>> -       to[i] = 0;
>> +       put_unaligned_le16(0, &to[i]);
>>        return i;
>>  }
>>
>> --
>> 1.7.3.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux