cifs: sanitize username handling
authorJeff Layton <jlayton@redhat.com>
Tue, 17 Jan 2012 21:09:15 +0000 (16:09 -0500)
committerSteve French <smfrench@gmail.com>
Wed, 18 Jan 2012 04:40:26 +0000 (22:40 -0600)
Currently, it's not very clear whether you're allowed to have a NULL
vol->username or ses->user_name. Some places check for it and some don't.

Make it clear that a NULL pointer is OK in these fields, and ensure that
all the callers check for that.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifs_spnego.c
fs/cifs/cifsencrypt.c
fs/cifs/connect.c

index 2272fd5fe5b74fcac62d001987ce3980a8a0b3e0..e622863b292f736fc8cc6e5d2ab8105986ad83bf 100644 (file)
@@ -113,9 +113,11 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
                   MAX_MECH_STR_LEN +
                   UID_KEY_LEN + (sizeof(uid_t) * 2) +
                   CREDUID_KEY_LEN + (sizeof(uid_t) * 2) +
-                  USER_KEY_LEN + strlen(sesInfo->user_name) +
                   PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
 
+       if (sesInfo->user_name)
+               desc_len += USER_KEY_LEN + strlen(sesInfo->user_name);
+
        spnego_key = ERR_PTR(-ENOMEM);
        description = kzalloc(desc_len, GFP_KERNEL);
        if (description == NULL)
@@ -152,8 +154,10 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
        dp = description + strlen(description);
        sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
 
-       dp = description + strlen(description);
-       sprintf(dp, ";user=%s", sesInfo->user_name);
+       if (sesInfo->user_name) {
+               dp = description + strlen(description);
+               sprintf(dp, ";user=%s", sesInfo->user_name);
+       }
 
        dp = description + strlen(description);
        sprintf(dp, ";pid=0x%x", current->pid);
index 5d9b9acc5fcebd1b9c9eff1ab3458acc19fbc72b..bce99e6a495001a8b7cc0182b922735fd4565dd4 100644 (file)
@@ -420,15 +420,20 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
        }
 
        /* convert ses->user_name to unicode and uppercase */
-       len = strlen(ses->user_name);
+       len = ses->user_name ? strlen(ses->user_name) : 0;
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL) {
                cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
                rc = -ENOMEM;
                return rc;
        }
-       len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
-       UniStrupr(user);
+
+       if (len) {
+               len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
+               UniStrupr(user);
+       } else {
+               memset(user, '\0', 2);
+       }
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
                                (char *)user, 2 * len);
index a66dcb52988c0da21671935c8a1ad6d2aba04aa5..b952a21e917b3aaa9cd12f7475b07f4580aeec7f 100644 (file)
@@ -1997,10 +1997,16 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
                        return 0;
                break;
        default:
+               /* NULL username means anonymous session */
+               if (ses->user_name == NULL) {
+                       if (!vol->nullauth)
+                               return 0;
+                       break;
+               }
+
                /* anything else takes username/password */
-               if (ses->user_name == NULL)
-                       return 0;
-               if (strncmp(ses->user_name, vol->username,
+               if (strncmp(ses->user_name,
+                           vol->username ? vol->username : "",
                            MAX_USERNAME_SIZE))
                        return 0;
                if (strlen(vol->username) != 0 &&
@@ -3167,10 +3173,9 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
                return -EINVAL;
 
        if (volume_info->nullauth) {
-               cFYI(1, "null user");
-               volume_info->username = kzalloc(1, GFP_KERNEL);
-               if (volume_info->username == NULL)
-                       return -ENOMEM;
+               cFYI(1, "Anonymous login");
+               kfree(volume_info->username);
+               volume_info->username = NULL;
        } else if (volume_info->username) {
                /* BB fixme parse for domain name here */
                cFYI(1, "Username: %s", volume_info->username);