Handle big endianness in NTLM (ntlmv2) authentication
Steve French [Tue, 25 Jun 2013 19:03:16 +0000 (14:03 -0500)]
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

fs/cifs/cifs_unicode.h
fs/cifs/cifsencrypt.c

index a513a54..f2b2ffd 100644 (file)
@@ -323,14 +323,14 @@ UniToupper(register wchar_t uc)
 /*
  * 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 = UniToupper(*up);
+               *up = cpu_to_le16(UniToupper(le16_to_cpu(*up)));
                up++;
        }
        return upin;            /* Return input pointer */
index 63c460e..6d0c62a 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];
-       wchar_t *user;
+       __le16 *user;
        wchar_t *domain;
        wchar_t *server;
 
@@ -419,7 +419,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
                return rc;
        }
 
-       /* convert ses->user_name to unicode and uppercase */
+       /* convert ses->user_name to unicode */
        len = ses->user_name ? strlen(ses->user_name) : 0;
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL) {
@@ -429,7 +429,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
        }
 
        if (len) {
-               len = cifs_strtoUTF16((__le16 *)user, ses->user_name, len, nls_cp);
+               len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
                UniStrupr(user);
        } else {
                memset(user, '\0', 2);