libsmbclient: smbc_stat buffer overflow

derrell at samba.org derrell at samba.org
Thu Apr 26 00:31:31 GMT 2007


Johannes Bauer <dfnsonfsduifb at gmx.de> writes:

> Hello list,
>
> I've recently encountered a problem with libsmbclient which causes the
> smb_stat function to write over the "struct stat" buffer exactly 8 bytes
> on x86_32 (i686) systems. x86_64 seems not to be affected.
>
> Affected versions:
>   3.0.22 (Ubuntu)
>   3.0.24 (Gentoo)
>   3.0.24 (Gentoo, different system)
>
> This program demonstrates the problem (replace //joeserver/transfer by a
> valid samba share, of course):

You don't indicate how you compiled this program, but I suspect that
libsmbclient is compiled for large file support, while your application is
not.  That would cause libsmbclient to be using different size fields in
struct stat than your program is assuming.

Please try compiling your program with these additional compile flags, and
confirm that this fixes the problem (or not):

  -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64

Cheers,

Derrell


> #include <stdio.h>
> #include <errno.h>
> #include <sys/time.h>
> #include <string.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <libsmbclient.h>
>
> struct smbstat {
> 	struct stat stat;
> 	unsigned char pad[16];
> };
>
> static void Authentication_Function(const char *pServer, const char
> *pShare, char *pWorkgroup, int workgroup_len, char *pUsername, int
> username_len, char *pPassword, int password_len) {
>     strncpy(pUsername, "guest", username_len);
>     strncpy(pPassword, "", password_len);
> }
>
> int main(int argc, char **argv) {
> 	int dir;
> 	struct smbc_dirent *Directory_Entry;
> 	char Buffer[256];
>
> 	if (smbc_init(Authentication_Function, 0) != 0) {
> 		fprintf(stderr, "smblister: Could not initialize smbc-library.\n");
> 		exit(6);
> 	}
>
> 	dir = smbc_opendir("smb://joeserver/transfer");
> 	
> 	while ((Directory_Entry = smbc_readdir(dir)) != NULL) {
> 		if (Directory_Entry->smbc_type == SMBC_FILE) {
> 			int i;
> 			off_t Filesize;
> 			struct smbstat Filestats;
> 			memset(&Filestats, 0x63, sizeof(struct smbstat));
> 			snprintf(Buffer, sizeof(Buffer), "smb://joeserver/transfer/%s",
> Directory_Entry->name);
> 			if (!smbc_stat(Buffer, (struct stat*)&Filestats)) {
> 				Filesize = Filestats.stat.st_size;
> 			} else {
> 				Filesize = 0;
> 			}
> 			printf("%s %ld\n", Directory_Entry->name, Filesize);
> 			for (i = 0; i < 16; i++) printf("%02x ", Filestats.pad[i]);
> 			printf("\n");
> 		}
> 	}
> 	
> 	smbc_closedir(dir);
> 	return 0;
> }
>
> And the output on an i686 machine:
>
> out.bmp 3932214
> 16 2f 00 00 00 00 00 00 63 63 63 63 63 63 63 63
> x.pdf 296844
> 14 09 00 00 00 00 00 00 63 63 63 63 63 63 63 63
>
> Clearly it can be seen that the first eight bytes of "pad" become
> overwritten.
>
> I've traced this error down to this point - it has, of course,
> catastrophal consequences: programs using the smb_stat sometimes showed
> chrashing (segfaults) und undefined behaviour (defect samba contexts).
> Exploitation of this bug seems unlinkely, however.
>
> Please tell me what you think.
> Thank you,
> Greetings,
> Johannes
>
>

-- 


More information about the samba-technical mailing list