Hi there, I just built samba 4.1.17 with the gnu gcc options -fsanitize=address -fsanitize=undefine -Og -ggdb -fno-omit-frame-pointer and I got many runtime error messages from the sanitizer. This is running "make test" as root. Mostly they are due to memcpy called with NULL pointer(s), then qsort and memmove. They seem harmless because the length parameter is (always?) zero, but I believe they should be fixed anyway, as in if(len) memcpy(target,null-pointer,len) Then there are undefined shifts like 1<<31 which should be 1u<<31 and more undefined shifts like 189<<24 which does not fit into the 'int' type. Maybe these are important and not so harmless. I have an x86-64 architecture under Linux 4.1.5 distribution Fedora 21. gnu gcc is at level 5.2.0. This is important. I put a /*vz*/ comment at or near the lines I changed to "fix" these issues, a few are BAD, I do not know how to fix them, a grep follows: ./libcli/smb/smb1cli_trans.c: if(state->num_setup) memcpy(vwv + 14, state->setup,/*vz*/ ./libcli/smb/smbXcli_base.c: if(iov[i].iov_len) memcpy(buf+copied, iov[i].iov_base, iov[i].iov_len);/*vz*/ ./lib/talloc/talloc.c: if(size) memcpy(newp, p, size);/*vz*/ ./lib/socket_wrapper/socket_wrapper.c: if(this_time) memcpy(buf + ofs,/*vz*/ ./lib/util/idtree.c:/*vz*/ ./lib/util/asn1.c: if(len) memcpy(data->data + data->ofs, p, len);/*vz*/ ./lib/util/bitmap.c: bm->b[i/32] |= (1u<<(i%32));/*vz*/ ./lib/util/bitmap.c: bm->b[i/32] &= ~(1u<<(i%32));/*vz*/ ./lib/util/bitmap.c: if (bm->b[i/32] & (1u<<(i%32))) { /*vz*/ ./lib/krb5_wrap/enctype_convert.c: uint32_t bit_value = (1u<< i) & enctype_bitmap;/*vz*/ ./lib/crypto/md4.c:M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |/*vz*//*runtime error: left shift of 189 by 24 places cannot be represented in type 'int'*/ ./lib/crypto/md4.c: if(n) memcpy(buf, in, n);/*vz*/ ./librpc/ndr/libndr.h:/* set to avoid recursion in ndr_size_*() calculation */ /*vz*/ #define LIBNDR_FLAG_NO_NDR_SIZE (1u<<31) ./librpc/ndr/ndr_basic.c: if(n) memcpy(ndr->data + ndr->offset, data, n);/*vz*/ ./source4/libcli/raw/rawtrans.c: if(parms->in.params.length) memcpy(req->out.data,/*vz*/ ./source4/libcli/raw/rawtrans.c: if(parms->in.data.length) memcpy(req->out.data + parms->in.params.length,/*vz*/ ./source4/libcli/raw/rawtrans.c: if(parms->in.setup_count) memcpy(req->out.vwv,/*vz*/ ./source4/libcli/raw/rawtrans.c: if(parms->in.data.length) memcpy(req->out.data + parms->in.params.length,/*vz*/ ./source4/libcli/raw/rawrequest.c: if(blob->length) memcpy(req->out.data + req->out.data_size, blob->data, blob->length);/*vz*/ ./source4/libcli/raw/raweas.c:if(eas[i].value.length) memcpy(data+4+nlen+1, eas[i].value.data, eas[i].value.length);/*vz*/ ./source4/libcli/raw/clitransport.c:assert(transport);/*vz*/ smbXcli_conn_disconnect(transport->conn, status); /* BAD: here transport == NULL */ ./source4/ntvfs/common/brlock_tdb.c: if(dbuf.dsize) memcpy(locks, dbuf.dptr, dbuf.dsize);/*vz*/ ./source4/torture/smb2/dir.c:/*vz*//*BAD: index 702 out of bounds for type 'file_elem [702]'*/ files[num_files + 2].name = talloc_asprintf(mem_ctx, "T013-13.txt.3"); /*BAD*/ ./source4/dsdb/kcc/kcc_topology.c: if(internal_edges.count) qsort(internal_edges.data, internal_edges.count,/*vz*/ ./source4/heimdal/lib/asn1/der_put.c: if(data->length) memcpy (p+1, data->data, data->length);/*vz*/ ./source4/heimdal/lib/krb5/store_emem.c: if(size) memmove(s->ptr, data, size);/*vz*/ ./source4/heimdal/lib/krb5/crypto.c: if(len) memcpy(ipad + cm->blocksize, data, len);/*vz*/ ./source4/smb_server/smb/nttrans.c: if(trans->out.setup_count) memcpy((char *)(this_req->out.vwv) + VWV(18), trans->out.setup,/*vz*/ ./bin/default/include/public/ndr.h:/* set to avoid recursion in ndr_size_*() calculation */ /*vz*/ #define LIBNDR_FLAG_NO_NDR_SIZE (1u<<31) ./source3/lib/dbwrap/dbwrap_watch.c: if(value.dsize) memcpy(ids, value.dptr, value.dsize);/*vz*/ ./source3/lib/util_tdb.c: if(i) memcpy(buf+4, s, i); /*vz*/ ./source3/smbd/notify_internal.c: if(value.dsize) memcpy(entries, value.dptr, value.dsize);/*vz*/ ./source3/smbd/trans2.c: if(ea_list->ea.value.length) memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);/*vz*/ ./source3/libsmb/errormap.c: for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) {/*vz*//*BAD: index 249 out of bounds for type '<unknown> [249]'*/ ./source3/libsmb/nmblib.c: name->name[n] = 0;/*vz*//*BAD: index 16 out of bounds for type 'char [16]'*/ source4/ntvfs/posix/pvfs_dirlist.c:241:35: runtime error: signed integer overflow: 9223372036854775807 + 2147483682 cannot be represented in type 'long int'
After downloading version 4.2.3 the following are the lines I changed or where the sanitizer found issues, some are BAD in my opinion ./libcli/smb/smb1cli_trans.c: if(state->num_setup) memcpy(vwv + 14, state->setup,/*vz*/ ./libcli/smb/smbXcli_base.c: if(iov[i].iov_len) memcpy(buf+copied, iov[i].iov_base, iov[i].iov_len);/*vz*/ ./libcli/cldap/cldap.c: if(blob1.length) memcpy(state->blob.data, blob1.data, blob1.length);/*vz*/ ./lib/talloc/talloc.c: if(size) memcpy(newp, p, size);/*vz*/ ./lib/socket_wrapper/socket_wrapper.c: if(this_time) memcpy(buf + ofs,/*vz*/ ./lib/util/idtree.c:/*vz*/ ./lib/util/idtree.c: ((id & ~(~0u<< MAX_ID_SHIFT)) >> (n + IDR_BITS))) { /*vz*/ ./lib/util/asn1.c: if(len) memcpy(data->data + data->ofs, p, len);/*vz*/ ./lib/util/bitmap.c: bm->b[i/32] |= (1u<<(i%32));/*vz*/ ./lib/util/bitmap.c: bm->b[i/32] &= ~(1u<<(i%32));/*vz*/ ./lib/util/bitmap.c: if (bm->b[i/32] & (1u<<(i%32))) {/*vz*/ ./lib/krb5_wrap/enctype_convert.c: uint32_t bit_value = (1u<< i) & enctype_bitmap;/*vz*/ ./lib/crypto/aes_cmac_128.c: if(len) memcpy(&tmp_block[ctx->last_len], msg, len);/*vz*/ ./lib/crypto/md4.c: if(n) memcpy(buf, in, n);/*vz*/ ./librpc/ndr/libndr.h:/*vz*/ ./librpc/ndr/ndr_basic.c: if(n) memcpy(ndr->data + ndr->offset, data, n);/*vz*/ grep: ./st: Permission denied ./source4/libcli/raw/rawtrans.c: if(parms->in.setup_count) memcpy(req->out.vwv,/*vz*/ ./source4/libcli/raw/rawrequest.c: if(blob->length) memcpy(req->out.data + req->out.data_size, blob->data, blob->length);/*vz*/ ./source4/ntvfs/common/brlock_tdb.c: if(dbuf.dsize) memcpy(locks, dbuf.dptr, dbuf.dsize);/*vz*/ ./source4/ntvfs/posix/pvfs_dirlist.c:dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE;/*vz*//*BAD: signed integer overflow: 9223372036854775807 + 2147483682 cannot be represented in type 'long int'*/ ./source4/dsdb/kcc/kcc_topology.c: if(internal_edges.count) qsort(internal_edges.data, internal_edges.count,/*vz*/ ./source4/heimdal/lib/asn1/der_put.c: if(data->length) memcpy (p+1, data->data, data->length);/*vz*/ ./source4/heimdal/lib/krb5/store_emem.c: if(size) memmove(s->ptr, data, size);/*vz*/ ./source4/heimdal/lib/krb5/crypto.c: if(len) memcpy(ipad + cm->blocksize, data, len);/*vz*/ ./source4/heimdal/lib/krb5/crypto.c: keyusage = CHECKSUM_USAGE(usage);/*vz*/ /*left shift of negative value -21*/ ./source4/heimdal/lib/krb5/crypto.c: keyusage = CHECKSUM_USAGE(usage);/*vz*/ /*left shift of negative value -21*/ ./source4/heimdal/lib/hcrypto/des.c: t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];/*vz*//*left shift of 186 by 24 places cannot be represented in type 'int'*/ ./source4/heimdal/lib/hcrypto/des.c: v[0] = b[0] << 24;/*vz*/ ./source4/heimdal/lib/hcrypto/des.c: v[1] = b[4] << 24;/*vz*/ ./source4/smb_server/smb/nttrans.c: if(trans->out.setup_count) memcpy((char *)(this_req->out.vwv) + VWV(18), trans->out.setup,/*vz*/ ./source4/smb_server/smb/reply.c: if(io->spnego.out.secblob.length) memcpy(req->out.data, io->spnego.out.secblob.data, io->spnego.out.secblob.length);/*vz*/ ./bin/default/include/public/ndr.h:/*vz*/ ./source3/lib/messages.c: int64_t fds64[MIN(num_fds, INT8_MAX)];/*vz*//*num_fds==0*/ ./source3/lib/dbwrap/dbwrap_watch.c: if(value.dsize) memcpy(ids, value.dptr, value.dsize);/*vz*/ ./source3/lib/util_tdb.c: if(i) memcpy(buf+4, s, i);/*vz*/ ./source3/lib/util_sock.c: if(len) memcpy(p, iov[i].iov_base, len);/*vz*/ ./source3/rpc_server/winreg/srv_winreg_nt.c: if(outbuf_size) memcpy(r->out.data, outbuf, outbuf_size);/*vz*/ ./source3/rpc_server/spoolss/srv_spoolss_nt.c: if(val_size) memcpy(r->out.data, val_data, val_size);/*vz*/ ./source3/smbd/notify_internal.c: if(value.dsize) memcpy(entries, value.dptr, value.dsize);/*vz*/ ./source3/smbd/trans2.c: if(ea_list->ea.value.length) memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);/*vz*/ ./source3/smbd/trans2.c: SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), snum)) ^ /*vz*//*left shift of negative value -690670082*/ ./source3/libsmb/nmblib.c: name->name[n] = 0;/*vz*//*BAD: index 16 out of bounds for type 'char [16]'*/ ./source3/locking/brlock.c: if(lock_len) memcpy(data.dptr, br_lck->lock_data, lock_len);/*vz*/ ./source3/locking/posix.c: if(value.dsize) memcpy(fds, value.dptr, value.dsize);/*vz*/
While we should go back and check the older releases in case of security issues, Samba development is done first in git master. If you can run on that, it will be easier to get started on any patches you propose, or others glean from the output. Thanks!
Unfortunately I do not have time to look at the git version. Version 4.2.3 is better that 4.1.17 concerning the sanitizer. But I believe at least the out of bounds array access source3/libsmb/nmblib.c: name->name[n] = 0;/*vz*//*BAD: index 16 out of bounds for type 'char [16]'*/ should be fixed. The overflows should be looked at.
Created attachment 11426 [details] git-am fix for master. Can you try this (which fixes the specific error you called out) ? It's not a security issue as: struct nmb_name { nstring name; char scope[64]; unsigned int name_type; }; which means overflowing the name field will overwrite scope, but not anything else.
In source4/auth/ntlm/auth_sam.c:415 the statement allowed_period = allowed_period_mins * 60 * 1000*1000*10; is undefined because the constant does not fit in the int type. The following is correct allowed_period = allowed_period_mins * 600000000L; The L suffix denotes a 'long int' constant. auth_sam.c has to do with passwords so maybe this is a secutity issue.
(In reply to Vittorio from comment #5) I'll take a look at this. In the meantime can you confirm the fix I posted for the previous issue ?
(In reply to Vittorio from comment #5) OK, this is a bug, not a security issue. If: allowed_period = allowed_period_mins * 60 * 1000*1000*10; is truncated, then the Samba AD-DC will return NT_STATUS_WRONG_PASSWORD instead of allowing the user in, so it's failing closed. Your fix is still valid, and I'll update the patch to include it ! Cheers, Jeremy.
Created attachment 11433 [details] Updated fix for master. Includes both patches. Can you confirm this fixes your issues ?
Yes, I'll look into the new patch. I remind you that there are several places where a left shift is undefined because it does not fit in its type, usually 'int'', as in source3/smbd/process.c:290:2: runtime error: left shift of 56321 by 16 places cannot be represented in type 'int source4/heimdal/lib/hcrypto/des.c:337:18: runtime error: left shift of 169 by 24 places cannot be represented in type 'int' source3/lib/util.c:211:2: runtime error: left shift of 46336 by 16 places cannot be represented in type 'int' source3/locking/posix.c:107:21: runtime error: left shift of 4611686018427387904 by 1 places cannot be represented in type 'long int' lib/crypto/md4.c:115:20: runtime error: left shift of 175 by 24 places cannot be represented in type 'int' libcli/smb/smbXcli_base.c:3072:2: runtime error: left shift of 36869 by 16 places cannot be represented in type 'int' source3/smbd/trans2.c:3394:2: runtime error: left shift of 1090422573 by 16 places cannot be represented in type 'int' source3/lib/sysquotas_linux.c:321:24: runtime error: left shift of 8388615 by 8 places cannot be represented in type 'int' libcli/smb/smb_seal.c:59:2: runtime error: left shift of 54272 by 16 places cannot be represented in type 'int' source4/smb_server/smb/reply.c:877:36: runtime error: left shift of 65534 by 16 places cannot be represented in type 'int' These are on version 4.2.3
Created attachment 14778 [details] git-am fix for 4.9.next, 4.8.next cherry-picked from master. Applies cleanly to 4.9.next, 4.8.next.
Comment on attachment 14778 [details] git-am fix for 4.9.next, 4.8.next cherry-picked from master. Looks good.
@Karo: please merge for maintenance branches.
(In reply to David Disseldorp from comment #12) Pushed to autobuild-v4-{9,8}-test.
(In reply to Karolin Seeger from comment #13) Pushed to both branches. Closing out bug report. Thanks!