Handle big endianness in NTLM (ntlmv2) authentication
authorSteve French <smfrench@us.ibm.com>
Tue, 25 Jun 2013 19:03:16 +0000 (14:03 -0500)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 27 Jul 2013 04:34:20 +0000 (05:34 +0100)
commit fdf96a907c1fbb93c633e2b7ede3b8df26d6a4c0 upstream.

This is RH bug 970891
Uppercasing of username during calculation of ntlmv2 hash fails
because UniStrupr function does not handle big endian wchars.

Also fix a comment in the same code to reflect its correct usage.

[To make it easier for stable (rather than require 2nd patch) fixed
this patch of Shirish's to remove endian warning generated
by sparse -- steve f.]

Reported-by: steve <sanpatr1@in.ibm.com>
Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
[bwh: Backported to 3.2: adjust context, indentation]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
fs/cifs/cifs_unicode.h
fs/cifs/cifsencrypt.c

index 6d02fd5..aab18fe 100644 (file)
@@ -323,14 +323,14 @@ UniToupper(register wchar_t uc)
 /*
  * UniStrupr:  Upper case a unicode string
  */
 /*
  * UniStrupr:  Upper case a unicode string
  */
-static inline wchar_t *
-UniStrupr(register wchar_t *upin)
+static inline __le16 *
+UniStrupr(register __le16 *upin)
 {
 {
-       register wchar_t *up;
+       register __le16 *up;
 
        up = upin;
        while (*up) {           /* For all characters */
 
        up = upin;
        while (*up) {           /* For all characters */
-               *up = UniToupper(*up);
+               *up = cpu_to_le16(UniToupper(le16_to_cpu(*up)));
                up++;
        }
        return upin;            /* Return input pointer */
                up++;
        }
        return upin;            /* Return input pointer */
index 5d9b9ac..cdcd665 100644 (file)
@@ -394,7 +394,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
        int rc = 0;
        int len;
        char nt_hash[CIFS_NTHASH_SIZE];
        int rc = 0;
        int len;
        char nt_hash[CIFS_NTHASH_SIZE];
-       wchar_t *user;
+       __le16 *user;
        wchar_t *domain;
        wchar_t *server;
 
        wchar_t *domain;
        wchar_t *server;
 
@@ -419,7 +419,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
                return rc;
        }
 
                return rc;
        }
 
-       /* convert ses->user_name to unicode and uppercase */
+       /* convert ses->user_name to unicode */
        len = strlen(ses->user_name);
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL) {
        len = strlen(ses->user_name);
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL) {
@@ -427,7 +427,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
                rc = -ENOMEM;
                return rc;
        }
                rc = -ENOMEM;
                return rc;
        }
-       len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
+       len = cifs_strtoUCS(user, ses->user_name, len, nls_cp);
        UniStrupr(user);
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
        UniStrupr(user);
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,