Bug 5589 - Segfaults in client library from Samba4 alpha 4
Summary: Segfaults in client library from Samba4 alpha 4
Status: RESOLVED WORKSFORME
Alias: None
Product: Samba 4.0
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: x86 Linux
: P3 normal (vote)
Target Milestone: ---
Assignee: Jelmer Vernooij
QA Contact: Andrew Bartlett
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-06 03:40 UTC by Rafał Cygnarowski
Modified: 2008-11-02 17:24 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rafał Cygnarowski 2008-07-06 03:40:33 UTC
Test program which uses samba client library crashes with following backtrace:

Program received signal SIGSEGV, Segmentation fault.
0xb7edfb92 in push_ucs2_talloc (ctx=0x8061590, ic=0x8057188, dest=0x8061590, src=0x0) at lib/charset/charcnv.c:477
477             size_t src_len = strlen(src)+1;
(gdb) bt
#0  0xb7edfb92 in push_ucs2_talloc (ctx=0x8061590, ic=0x8057188, dest=0x8061590, src=0x0) at lib/charset/charcnv.c:477
#1  0xb7ee66d4 in msrpc_gen (mem_ctx=0x8061508, iconv_convenience=0x8057188, blob=0xbf8d8e04, format=0xb7f16fc6 "aaa") at auth/ntlmssp/ntlmssp_parse.c:93
#2  0xb7ed47a6 in NTLMv2_generate_names_blob (mem_ctx=0x8061508, iconv_convenience=0x8057188, hostname=0x8058b58 "kajtek", domain=0x0)
    at libcli/auth/smbencrypt.c:305
#3  0xb7ca30f9 in session_setup_old (c=<value optimized out>, session=0x80590d8, io=0x8059008, req=0x8061554) at libcli/smb_composite/sesssetup.c:295
#4  0xb7ca3e20 in smb_composite_sesssetup_send (session=0x80590d8, io=0x8059008) at libcli/smb_composite/sesssetup.c:488
#5  0xb7ca2d1f in state_handler (c=0x8058990) at libcli/smb_composite/connect.c:261
#6  0xb7ca9fa6 in smbcli_transport_finish_recv (private=0x8058e70, blob={data = 0x8061580 "p�\024�", length = 73}) at libcli/raw/clitransport.c:486
#7  0xb7d50034 in packet_recv (pc=0x8058f48) at lib/stream/packet.c:378
#8  0xb7ca98ad in smbcli_transport_event_handler (ev=0x8058370, fde=0x8058d00, flags=1, private=0x8058e70) at libcli/raw/clitransport.c:44
#9  0xb7d7f537 in std_event_loop_once (ev=0x8058370) at lib/events/events_standard.c:320
#10 0xb7ee9a2e in event_loop_once (ev=0x8058370) at lib/events/events.c:294
#11 0xb7d7d174 in composite_wait (c=0x8058990) at libcli/composite/composite.c:64
#12 0xb7ca2396 in smb_composite_connect_recv (c=0x8058990, mem_ctx=0x804a090) at libcli/smb_composite/connect.c:497
#13 0xb7ca2516 in smb_composite_connect (io=0xbf8d925c, mem_ctx=0x804a090, resolve_ctx=0x8057870, ev=0x8058370) at libcli/smb_composite/connect.c:516
#14 0xb7caaf88 in smbcli_tree_full_connection (parent_ctx=0x804a090, ret_tree=0xbf8d92f8, dest_host=0x8048c9a "kajtek", dest_ports=0x804c4e0,
    service=0x8048c95 "test", service_type=0x0, credentials=0x8057090, resolve_ctx=0x8057870, ev=0x8058370, options=0xbf8d9368) at libcli/raw/clitree.c:204
#15 0xb7c945f4 in smbcli_full_connection (parent_ctx=0x804a090, ret_cli=0x8049e9c, host=0x8048c9a "kajtek", ports=0x804c4e0, sharename=0x8048c95 "test",
    devtype=0x0, credentials=0x8057090, resolve_ctx=0x8057870, ev=0x8058370, options=0xbf8d9350) at libcli/cliconnect.c:154
#16 0x08048b1f in main ()

Here's example program for tests:
#include "includes.h"
#include "version.h"
#include "libcli/libcli.h"
#include "lib/cmdline/popt_common.h"
#include "librpc/gen_ndr/ndr_srvsvc_c.h"
#include "librpc/gen_ndr/ndr_lsa.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/util/clilsa.h"
#include "system/dir.h"
#include "system/filesys.h"
#include "lib/util/dlinklist.h"
#include "system/readline.h"
#include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h"
#include "system/time.h"
#include "libcli/resolve/resolve.h"
#include "libcli/security/security.h"
#include "lib/smbreadline/smbreadline.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
#include "lib/events/events.h"

TALLOC_CTX *mem_ctx;
struct smbcli_state *cli = NULL;
int seq = 0, ns = 0;

extern const char *dyn_CONFIGFILE;

int main (int argc, char *argv[])
{
	struct cli_credentials *cred;
	struct event_context *ev_ctx;

	char *server = "server";
	char *share = "share";
	char *username = "user";
	char *password = "password";

	NTSTATUS status;
	struct loadparm_context *lp_ctx, *cmdline_lp_ctx;
	struct smbcli_options smb_options;

	mem_ctx = talloc_init("main.c/main");
	if (!mem_ctx) {
		printf("main.c: Not enough memory.\n");
		return 1;
	}

	if (global_loadparm != NULL) {
		lp_ctx = global_loadparm;
	} else {
		lp_ctx = global_loadparm = loadparm_init(talloc_autofree_context());
	}

	if (!(cli = smbcli_state_init(NULL))) {
		printf("smbcli_state_init failed!\n");
		return 1;
	}
		
	if (lp_configfile(lp_ctx) == NULL) {
		if (getenv("SMB_CONF_PATH"))
			lp_load(lp_ctx, getenv("SMB_CONF_PATH"));
		else
			lp_load(lp_ctx, dyn_CONFIGFILE);
	}	

	cmdline_lp_ctx = lp_ctx;
	status = gensec_init(cmdline_lp_ctx);
	if (!NT_STATUS_IS_OK(status)) {
		printf("gensec_init failed\n");
		return 1;
	}


	if (!lp_set_cmdline(lp_ctx, "client max protocol", "LANMAN1")) {
		printf("error while setting up protocol\n");
		return 1;
	}

	cred = cli_credentials_init(mem_ctx);
	if (!cred) {
		printf("cli_credentails_init_anon failed\n");
		return 1;
	}

	cli_credentials_guess(cred, lp_ctx);
	if (!cli_credentials_set_username(cred, username, CRED_SPECIFIED)) {
		printf("cli_credentails_set_username failed\n");
		return 1;
	}
                                                                                	
	if (!cli_credentials_set_password(cred, password, CRED_SPECIFIED)) {
		printf("cli_credentails_set_password failed\n");
		return 1;	
	}

	lp_smbcli_options(cmdline_lp_ctx, &smb_options);
	ev_ctx = event_context_init(talloc_autofree_context());

        status = smbcli_full_connection(
        	mem_ctx, &cli, server, 
        	lp_smb_ports(lp_ctx), 
        	share, NULL, cred, 
        	lp_resolve_context(cmdline_lp_ctx),
        	ev_ctx, &smb_options
        );
	
	if (!NT_STATUS_IS_OK(status)) {
		printf("Connection to \\\\%s\\%s failed - %s\n", server, share, nt_errstr(status));
		return 1;
	}

	return 0;
}
Comment 1 Andrew Kroeger 2008-07-07 02:56:15 UTC
The problem stems from the fact that the domain (last parameter) being passed to NTLMv2_generate_names_blob() is NULL.  The value of this parameter comes from 'lp_workgroup(global_loadparm)' (see line 295 of libcli/smb_composite/sesssetup.c).

It appears that you do not have any workgroup defined in your configuration.  Based on the sample program you posted, I can see 2 possible issues:

1.  There is no workgroup defined in whatever configuration file is being used.

2.  No configuration file is found at all.  You do not check the return value of lp_load(), so if there is an error here, I'm not sure how the rest of the program is expected to behave.

Does making sure you have a workgroup defined in the configuration file that is being used correct the problem?
Comment 2 Rafał Cygnarowski 2008-07-07 09:50:18 UTC
> It appears that you do not have any workgroup defined in your configuration. 
> Based on the sample program you posted, I can see 2 possible issues:

I used to check if client library works fine with smbclient build while client library is build. There's no problem connecting with this client to my server even if there is NO config file at all - so, this is not the issue.

Anyway... I checked with configuration file also (lp_load returned true), here's the backtrace:

Program received signal SIGSEGV, Segmentation fault.
0xb7e82b92 in push_ucs2_talloc (ctx=0x8061c38, ic=0x80578e8, dest=0x8061c38, src=0x0) at lib/charset/charcnv.c:477
477             size_t src_len = strlen(src)+1;
(gdb) bt
#0  0xb7e82b92 in push_ucs2_talloc (ctx=0x8061c38, ic=0x80578e8, dest=0x8061c38, src=0x0) at lib/charset/charcnv.c:477
#1  0xb7e896d4 in msrpc_gen (mem_ctx=0x8061bb0, iconv_convenience=0x80578e8, blob=0xbf846574, format=0xb7eb9fc6 "aaa") at auth/ntlmssp/ntlmssp_parse.c:93
#2  0xb7e777a6 in NTLMv2_generate_names_blob (mem_ctx=0x8061bb0, iconv_convenience=0x80578e8, hostname=0x8059290 "kajtek", domain=0x0)
    at libcli/auth/smbencrypt.c:305
#3  0xb7c460f9 in session_setup_old (c=<value optimized out>, session=0x80596f8, io=0x8059798, req=0x8061bfc) at libcli/smb_composite/sesssetup.c:295
#4  0xb7c46e20 in smb_composite_sesssetup_send (session=0x80596f8, io=0x8059798) at libcli/smb_composite/sesssetup.c:488
#5  0xb7c45d1f in state_handler (c=0x80590c8) at libcli/smb_composite/connect.c:261
#6  0xb7c4cfa6 in smbcli_transport_finish_recv (private=0x80595a8, blob={data = 0x8061cb8 "", length = 73}) at libcli/raw/clitransport.c:486
#7  0xb7cf3034 in packet_recv (pc=0x8059680) at lib/stream/packet.c:378
#8  0xb7c4c8ad in smbcli_transport_event_handler (ev=0x8058a60, fde=0x8059438, flags=1, private=0x80595a8) at libcli/raw/clitransport.c:44
#9  0xb7d22537 in std_event_loop_once (ev=0x8058a60) at lib/events/events_standard.c:320
#10 0xb7e8ca2e in event_loop_once (ev=0x8058a60) at lib/events/events.c:294
#11 0xb7d20174 in composite_wait (c=0x80590c8) at libcli/composite/composite.c:64
#12 0xb7c45396 in smb_composite_connect_recv (c=0x80590c8, mem_ctx=0x804a090) at libcli/smb_composite/connect.c:497
#13 0xb7c45516 in smb_composite_connect (io=0xbf8469cc, mem_ctx=0x804a090, resolve_ctx=0x8057f88, ev=0x8058a60) at libcli/smb_composite/connect.c:516
#14 0xb7c4df88 in smbcli_tree_full_connection (parent_ctx=0x804a090, ret_tree=0xbf846a68, dest_host=0x8048d65 "kajtek", dest_ports=0x804c4e0,
    service=0x8048d60 "test", service_type=0x0, credentials=0x80577f0, resolve_ctx=0x8057f88, ev=0x8058a60, options=0xbf846ad8) at libcli/raw/clitree.c:204
#15 0xb7c375f4 in smbcli_full_connection (parent_ctx=0x804a090, ret_cli=0x8049f94, host=0x8048d65 "kajtek", ports=0x804c4e0, sharename=0x8048d60 "test",
    devtype=0x0, credentials=0x80577f0, resolve_ctx=0x8057f88, ev=0x8058a60, options=0xbf846ac0) at libcli/cliconnect.c:154
#16 0x08048b8f in main ()
Comment 3 Andrew Bartlett 2008-07-14 00:17:20 UTC
This certainly is odd, as we should have a default workgroup of 'workgroup' being returned.  

I think the problem comes from your global_loadparm handling.
Comment 4 Matthias Dieter Wallnöfer 2008-09-12 04:21:04 UTC
Did you test also later GIT releases of SAMBA 4?
Comment 5 Rafał Cygnarowski 2008-09-17 15:56:03 UTC
(In reply to comment #4)
> Did you test also later GIT releases of SAMBA 4?

Tested few minutes ago. Problem is still alive:

Program received signal SIGSEGV, Segmentation fault.
0xb7f831bd in push_ucs2_talloc (ctx=0x8061c20, ic=0x80579d8, dest=0x8061c20, src=0x0) at lib/charset/charcnv.c:477
477             size_t src_len = strlen(src)+1;
(gdb) bt
#0  0xb7f831bd in push_ucs2_talloc (ctx=0x8061c20, ic=0x80579d8, dest=0x8061c20, src=0x0) at lib/charset/charcnv.c:477
#1  0xb7f8db75 in msrpc_gen (mem_ctx=0x8061b98, iconv_convenience=0x80579d8, blob=0xbfe743a4, format=0xb7fa09a0 "aaa")
    at auth/ntlmssp/ntlmssp_parse.c:93
#2  0xb7f71aba in NTLMv2_generate_names_blob (mem_ctx=0x8061b98, iconv_convenience=0x80579d8, hostname=0x8059270 "kajtek", domain=0x0)
    at libcli/auth/smbencrypt.c:305
#3  0xb7d175d9 in session_setup_old (c=<value optimized out>, session=0x80596d8, io=0x8059778, req=0x8061be4)
    at libcli/smb_composite/sesssetup.c:295
#4  0xb7d183aa in smb_composite_sesssetup_send (session=0x80596d8, io=0x8059778) at libcli/smb_composite/sesssetup.c:488
#5  0xb7d171f1 in state_handler (c=0x80590a8) at libcli/smb_composite/connect.c:261
#6  0xb7d1e498 in smbcli_transport_finish_recv (private=0x8059588, blob={data = 0x8061ca0 "", length = 73})
    at libcli/raw/clitransport.c:509
#7  0xb7d76071 in packet_recv (pc=0x8059660) at lib/stream/packet.c:378
#8  0xb7d1ddab in smbcli_transport_event_handler (ev=0x8058a38, fde=0x8059418, flags=1, private=0x8059588) at libcli/raw/clitransport.c:44
#9  0xb7f700d3 in std_event_loop_once (ev=0x8058a38) at lib/events/events_standard.c:318
#10 0xb7f6cc5b in event_loop_once (ev=0x8058a38) at lib/events/events.c:283
#11 0xb7da1f53 in composite_wait (c=0x80590a8) at libcli/composite/composite.c:64
#12 0xb7d168c6 in smb_composite_connect_recv (c=0x80590a8, mem_ctx=0x804a090) at libcli/smb_composite/connect.c:497
#13 0xb7d16a46 in smb_composite_connect (io=0xbfe7475c, mem_ctx=0x804a090, resolve_ctx=0x8057fc0, ev=0x8058a38)
    at libcli/smb_composite/connect.c:516
#14 0xb7d1f3b7 in smbcli_tree_full_connection (parent_ctx=0x804a090, ret_tree=0xbfe747f8, dest_host=0x8048d95 "kajtek",
    dest_ports=0x804c558, service=0x8048d90 "test", service_type=0x0, credentials=0x80578e0, resolve_ctx=0x8057fc0, ev=0x8058a38,
    options=0xbfe74850) at libcli/raw/clitree.c:204
#15 0xb7d08c44 in smbcli_full_connection (parent_ctx=0x804a090, ret_cli=0x8049fc4, host=0x8048d95 "kajtek", ports=0x804c558,
    sharename=0x8048d90 "test", devtype=0x0, credentials=0x80578e0, resolve_ctx=0x8057fc0, ev=0x8058a38, options=0xbfe74850)
    at libcli/cliconnect.c:154
#16 0x08048acc in main () 
Comment 6 Matthias Dieter Wallnöfer 2008-09-17 17:00:28 UTC
Okay, I've analysed a bit your code: 

1.) Don't use three "loadparm_ctx" pointers. Two ("global_loadparm" and "lp_ctx") should be enough!

2.)
>        if (lp_configfile(lp_ctx) == NULL) {
>                if (getenv("SMB_CONF_PATH"))
>                        lp_load(lp_ctx, getenv("SMB_CONF_PATH"));
>                else
>                        lp_load(lp_ctx, dyn_CONFIGFILE);
>        }       
This seems to be your fault: you ask for the SAMBA configuration file (default "smb.conf") to see if it isn't defined (lp_configfile(lp_ctx)). And here comes the problem: When it isn't you should break, because you simply aren't able to load something. And if it is, you should get the settings. I would change this part to something like this (taken from "client/smbmount.c"):

if (!lp_load(lp_ctx, dyn_CONFIGFILE)) {
 fprintf(stderr, "Can't load %s - run testparm to debug it\n", lp_config_file());
}

So you know if the load-parameter worked.
Comment 7 Rafał Cygnarowski 2008-09-17 17:22:00 UTC
> This seems to be your fault:
I won't say no, but...

here's my test program after your suggestions and it still have problems:

#include "includes.h"
#include "version.h"
#include "libcli/libcli.h"
#include "lib/cmdline/popt_common.h"
#include "librpc/gen_ndr/ndr_srvsvc_c.h"
#include "librpc/gen_ndr/ndr_lsa.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/util/clilsa.h"
#include "system/dir.h"
#include "system/filesys.h"
#include "lib/util/dlinklist.h"
#include "system/readline.h"
#include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h"
#include "system/time.h"
#include "libcli/resolve/resolve.h"
#include "libcli/security/security.h"
#include "lib/smbreadline/smbreadline.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
#include "lib/events/events.h"

TALLOC_CTX *mem_ctx;
struct smbcli_state *cli = NULL;
int seq = 0, ns = 0;

extern const char *dyn_CONFIGFILE;

int main (int argc, char *argv[])
{
	struct cli_credentials *cred;
	struct event_context *ev_ctx;

	char *server = "kajtek";
	char *share = "test";
	char *username = "tester";
	char *password = "psiczek";

	NTSTATUS status;
	struct loadparm_context *lp_ctx;
	struct smbcli_options smb_options;

	mem_ctx = talloc_init("main.c/main");
	if (!mem_ctx) {
		printf("main.c: Not enough memory.\n");
		return 1;
	}

	if (global_loadparm != NULL) {
		lp_ctx = global_loadparm;
	} else {
		lp_ctx = global_loadparm = loadparm_init(talloc_autofree_context());
	}

	if (!(cli = smbcli_state_init(NULL))) {
		printf("smbcli_state_init failed!\n");
		return 1;
	}
		
	if (!lp_load(lp_ctx, dyn_CONFIGFILE))
		fprintf(stderr, "Can't load config file");

	status = gensec_init(lp_ctx);
	if (!NT_STATUS_IS_OK(status)) {
		printf("gensec_init failed\n");
		return 1;
	}


	if (!lp_set_cmdline(lp_ctx, "client max protocol", "LANMAN1")) {
		printf("error while setting up protocol\n");
		return 1;
	}

	cred = cli_credentials_init(mem_ctx);
	if (!cred) {
		printf("cli_credentails_init_anon failed\n");
		return 1;
	}

	cli_credentials_guess(cred, lp_ctx);
	if (!cli_credentials_set_username(cred, username, CRED_SPECIFIED)) {
		printf("cli_credentails_set_username failed\n");
		return 1;
	}
                                                                                	
	if (!cli_credentials_set_password(cred, password, CRED_SPECIFIED)) {
		printf("cli_credentails_set_password failed\n");
		return 1;	
	}

	lp_smbcli_options(lp_ctx, &smb_options);
	ev_ctx = event_context_init(talloc_autofree_context());

        status = smbcli_full_connection(
        	mem_ctx, &cli, server, 
        	lp_smb_ports(lp_ctx), 
        	share, NULL, cred, 
        	lp_resolve_context(lp_ctx),
        	ev_ctx, &smb_options
        );
	
	if (!NT_STATUS_IS_OK(status)) {
		printf("Connection to \\\\%s\\%s failed - %s\n", server, share, nt_errstr(status));
		return 1;
	}

	return 0;
}
Comment 8 Matthias Dieter Wallnöfer 2008-10-25 16:41:22 UTC
This will handle Jelmer now!
Comment 9 Jelmer Vernooij 2008-11-02 17:24:28 UTC
Global loadparm is now gone in git, this should fix this problem.