Bug 5530 - vuid and memory leak in smbd during successful NTLMSSP/Kerberos authentication
Summary: vuid and memory leak in smbd during successful NTLMSSP/Kerberos authentication
Status: RESOLVED FIXED
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: File Services (show other bugs)
Version: 3.0.25
Hardware: Other Linux
: P3 normal
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-06-09 17:22 UTC by Hames Kurma
Modified: 2008-06-19 18:57 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hames Kurma 2008-06-09 17:22:24 UTC
For NTLMSSP authentication, the authentication is performed through two session setup requests. The smbd allocates a vuid for each request, but fails to free the first vuid (vuid allocated in the first request). As a result, both vuid and memory of struct user is leaked.

This bug also occurs during Kerberos authentication.

The best way to reproduce the bug is to write a smbtoture test that opens a TCP connection and performs NTLMSSP session setups and logoff operation in a loop. After a while, the smbd fails session setup request with STATUS_INVALID_PARAMETER and logs "Too many vuids" in the log file. If there is rlimit on smbd, then smbd might reach that limit and fail with memory allocation error.

Without writing a new smbtoture test, the bug can be proved by looking at the variable num_validated_vuids in smbd after one successful NTLMSSP authentication. The correct value should be 1, but the actual value would be 2.

The bug is in reply_spnego_ntlmssp()/invalidate_vuid(). The reply_spnego_ntlmssp() calls invalidate_vuid() to free the first allocated vuid, but invalidate_vuid() does not free the vuid because the vuid is not "valid" according to get_valid_user_struct(), since the server_info is NULL for this user structure.

The bug is fixed by the following code changes identified by #ifdef BUGFIX:

void invalidate_vuid(uint16 vuid)
{
        user_struct *vuser = get_valid_user_struct(vuid);

#ifdef BUGFIX
        /*
         * For NTLMSPP, the second session setup request allocates a new vuid
         * and invalidates the first vuid. But the first vuid is not valid
         * (does not have server_info), hence get_valid_user_struct won't find
         * it. So use get_partial_auth_user_struct to find the vuser structure
         * for such vuid. Otherwise, both memory and vuid is leaked.
         */
        if (vuser == NULL) {
                vuser = get_partial_auth_user_struct(vuid);
        }
#endif /* BUGFIX */

        if (vuser == NULL)
                return;

        SAFE_FREE(vuser->homedir);
        SAFE_FREE(vuser->unix_homedir);
        SAFE_FREE(vuser->logon_script);

        session_yield(vuser);
        SAFE_FREE(vuser->session_keystr);

        TALLOC_FREE(vuser->server_info);

        data_blob_free(&vuser->session_key);

        DLIST_REMOVE(validated_users, vuser);

        /* clear the vuid from the 'cache' on each connection, and
           from the vuid 'owner' of connections */
        conn_clear_vuid_cache(vuid);

        SAFE_FREE(vuser->groups);
        TALLOC_FREE(vuser->nt_user_token);

        SAFE_FREE(vuser);
        num_validated_vuids--;
}
Comment 1 Hames Kurma 2008-06-09 17:26:04 UTC
Correct the bug summary.
Comment 2 Jeremy Allison 2008-06-19 18:57:39 UTC
This bug has already been fixed in 3.0.30 and 3.2.x (actually I think it was fixed around 3.0.28). Thanks for the report though. Please let me know if you can reproduce in a later version.

Jeremy.