Symbol clash in libsamba-util and libnetsnmp

Bjoern Baumbach bb at sernet.de
Mon Apr 14 08:20:01 MDT 2014


Hi!

We encountered a problem with the memdup() function in the
libsamba-util. The libnetsnmp provides also an own memdup() function and
typically this one does not use symbol versioning.
In this case the libsmbconf prefers the unversioned memdup() instead of
our own memdup().

I give an example:
A system uses the nss_wins module. A tool tries to get a host by name,
using the netsnmp_getaddrinfo() from the libnetsnmp. This ends in a
_nss_wins_gethostbyname_r() call by the nss_wins, which calls the
memdup() function of the libnetsnmp (instead of the memdup() of
libsamba-util()).

I think this backtrace explains this a bit better:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7886886 in __memcpy_ssse3_back () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7886886 in __memcpy_ssse3_back () from /lib64/libc.so.6
#1  0x00007ffff7b54724 in memdup () from /usr/lib64/libnetsnmp.so.30
#2  0x00007ffff5c56572 in load_interfaces () from /usr/lib64/libsmbconf.so.0
#3  0x00007ffff64f74ee in _nss_wins_gethostbyname_r () from
/usr/lib64/libnss_wins.so.2
#4  0x00007ffff7853601 in gethostbyname2_r () from /lib64/libc.so.6
#5  0x00007ffff7825e2f in gaih_inet () from /lib64/libc.so.6
#6  0x00007ffff7827de4 in getaddrinfo () from /lib64/libc.so.6
#7  0x00007ffff7b4b2bc in netsnmp_getaddrinfo () from
/usr/lib64/libnetsnmp.so.30
#8  0x00007ffff7b4b4c6 in netsnmp_gethostbyname_v4 () from
/usr/lib64/libnetsnmp.so.30
#9  0x00007ffff7b6933c in netsnmp_sockaddr_in2 () from
/usr/lib64/libnetsnmp.so.30
#10 0x00007ffff7b6c042 in netsnmp_udp_create_tstring () from
/usr/lib64/libnetsnmp.so.30
#11 0x00007ffff7b65289 in netsnmp_tdomain_transport_full () from
/usr/lib64/libnetsnmp.so.30
#12 0x00007ffff7b38fd3 in snmp_sess_open () from /usr/lib64/libnetsnmp.so.30
#13 0x00007ffff7b39229 in snmp_open () from /usr/lib64/libnetsnmp.so.30
#14 0x0000000000401714 in main ()


To avoid this I've renamed the (very common named) memdup() function to
smb_memdup(). Please find a patch attached.

Does anybody know how we can solve this in general? In the case of the
nss_wins we could reduce the large number of dependencies by using the
wins-resolving-functionality of the winbind client library.

Best regards
Björn

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 74be46d2b124a4c0d61858c7e45913a78b38d462 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb at sernet.de>
Date: Mon, 14 Apr 2014 14:37:29 +0200
Subject: [PATCH 1/2] lib-util: rename memdup to smb_memdup and fix all callers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Björn Baumbach <bb at sernet.de>
---
 ctdb/lib/util/util.h              | 2 +-
 lib/util/samba_util.h             | 2 +-
 lib/util/util.c                   | 2 +-
 source3/lib/interface.c           | 4 ++--
 source3/lib/smbldap.c             | 2 +-
 source3/libsmb/clirap.c           | 4 ++--
 source3/passdb/secrets.c          | 2 +-
 source3/smbd/seal.c               | 2 +-
 source3/smbd/sec_ctx.c            | 4 ++--
 source3/winbindd/winbindd_cache.c | 2 +-
 source4/smbd/process_thread.c     | 4 ++--
 11 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/ctdb/lib/util/util.h b/ctdb/lib/util/util.h
index 467fba8..9929d2e 100644
--- a/ctdb/lib/util/util.h
+++ b/ctdb/lib/util/util.h
@@ -524,7 +524,7 @@ char *smb_xstrndup(const char *s, size_t n);
 /**
  Like strdup but for memory.
 **/
-_PUBLIC_ void *memdup(const void *p, size_t size);
+_PUBLIC_ void *smb_memdup(const void *p, size_t size);
 
 /**
  * see if a range of memory is all zero. A NULL pointer is considered
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index f52347e..dcb92ee 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -739,7 +739,7 @@ char *smb_xstrndup(const char *s, size_t n);
 /**
  Like strdup but for memory.
 **/
-_PUBLIC_ void *memdup(const void *p, size_t size);
+_PUBLIC_ void *smb_memdup(const void *p, size_t size);
 
 /**
  * Write a password to the log file.
diff --git a/lib/util/util.c b/lib/util/util.c
index 2b73f63..11d7753 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -693,7 +693,7 @@ char *smb_xstrndup(const char *s, size_t n)
  Like strdup but for memory.
 **/
 
-_PUBLIC_ void *memdup(const void *p, size_t size)
+_PUBLIC_ void *smb_memdup(const void *p, size_t size)
 {
 	void *p2;
 	if (size == 0)
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 39dc9cb..3edeae5 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -503,10 +503,10 @@ void load_interfaces(void)
 	total_probed = get_interfaces(talloc_tos(), &ifaces);
 
 	if (total_probed > 0) {
-		probed_ifaces = (struct iface_struct *)memdup(ifaces,
+		probed_ifaces = (struct iface_struct *)smb_memdup(ifaces,
 				sizeof(ifaces[0])*total_probed);
 		if (!probed_ifaces) {
-			DEBUG(0,("ERROR: memdup failed\n"));
+			DEBUG(0,("ERROR: smb_memdup failed\n"));
 			exit(1);
 		}
 	}
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index 08640d0..f2d58a5 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -353,7 +353,7 @@ static void smbldap_set_mod_internal(LDAPMod *** modlist, int modop, const char
 		mods[i]->mod_bvalues[j] = SMB_MALLOC_P(struct berval);
 		SMB_ASSERT(mods[i]->mod_bvalues[j] != NULL);
 
-		mods[i]->mod_bvalues[j]->bv_val = (char *)memdup(blob->data, blob->length);
+		mods[i]->mod_bvalues[j]->bv_val = (char *)smb_memdup(blob->data, blob->length);
 		SMB_ASSERT(mods[i]->mod_bvalues[j]->bv_val != NULL);
 		mods[i]->mod_bvalues[j]->bv_len = blob->length;
 
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index 7e6f8d7..036919f 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -67,14 +67,14 @@ bool cli_api(struct cli_state *cli,
 	 * talloc
 	 */
 
-	*rparam = (char *)memdup(my_rparam, num_my_rparam);
+	*rparam = (char *)smb_memdup(my_rparam, num_my_rparam);
 	if (*rparam == NULL) {
 		goto fail;
 	}
 	*rprcnt = num_my_rparam;
 	TALLOC_FREE(my_rparam);
 
-	*rdata = (char *)memdup(my_rdata, num_my_rdata);
+	*rdata = (char *)smb_memdup(my_rdata, num_my_rdata);
 	if (*rdata == NULL) {
 		goto fail;
 	}
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 9d91c2f..bff9a0d 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -144,7 +144,7 @@ void *secrets_fetch(const char *key, size_t *size)
 		return NULL;
 	}
 
-	result = memdup(dbuf.dptr, dbuf.dsize);
+	result = smb_memdup(dbuf.dptr, dbuf.dsize);
 	if (result == NULL) {
 		return NULL;
 	}
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index bb9bb08..273013b 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -245,7 +245,7 @@ NTSTATUS srv_request_encryption_setup(connection_struct *conn,
 
 	/* Return the raw blob. */
 	SAFE_FREE(*ppdata);
-	*ppdata = (unsigned char *)memdup(response.data, response.length);
+	*ppdata = (unsigned char *)smb_memdup(response.data, response.length);
 	if ((*ppdata) == NULL && response.length > 0)
 		return NT_STATUS_NO_MEMORY;
 	*p_data_size = response.length;
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index d474219..c34247e6 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -331,8 +331,8 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct
 	TALLOC_FREE(ctx_p->token);
 
 	if (ngroups) {
-		ctx_p->ut.groups = (gid_t *)memdup(groups,
-						   sizeof(gid_t) * ngroups);
+		ctx_p->ut.groups = (gid_t *)smb_memdup(groups,
+						       sizeof(gid_t) * ngroups);
 		if (!ctx_p->ut.groups) {
 			smb_panic("memdup failed");
 		}
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index b9cfd82..9c4b5bd 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -3562,7 +3562,7 @@ static struct cache_entry *create_centry_validate(const char *kstr, TDB_DATA dat
 	struct cache_entry *centry;
 
 	centry = SMB_XMALLOC_P(struct cache_entry);
-	centry->data = (unsigned char *)memdup(data.dptr, data.dsize);
+	centry->data = (unsigned char *)smb_memdup(data.dptr, data.dsize);
 	if (!centry->data) {
 		SAFE_FREE(centry);
 		return NULL;
diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c
index 764c1f3..ad264c9 100644
--- a/source4/smbd/process_thread.c
+++ b/source4/smbd/process_thread.c
@@ -218,7 +218,7 @@ static void thread_set_title(struct tevent_context *ev, const char *title)
 static int thread_mutex_init(smb_mutex_t *mutex, const char *name)
 {
 	pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
-	mutex->mutex = memdup(&m, sizeof(m));
+	mutex->mutex = smb_memdup(&m, sizeof(m));
 	if (! mutex->mutex) {
 		errno = ENOMEM;
 		return -1;
@@ -294,7 +294,7 @@ static int thread_mutex_unlock(smb_mutex_t *mutex, const char *name)
 static int thread_rwlock_init(smb_rwlock_t *rwlock, const char *name)
 {
 	pthread_rwlock_t m = PTHREAD_RWLOCK_INITIALIZER;
-	rwlock->rwlock = memdup(&m, sizeof(m));
+	rwlock->rwlock = smb_memdup(&m, sizeof(m));
 	if (! rwlock->rwlock) {
 		errno = ENOMEM;
 		return -1;
-- 
1.8.3.2


From 2268edcd9cc36485b3ac5fe760dd1d37c96c0880 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb at sernet.de>
Date: Mon, 14 Apr 2014 14:42:56 +0200
Subject: [PATCH 2/2] s3: use smb_xmemdup instead of smb_memdup and smb_panic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Björn Baumbach <bb at sernet.de>
---
 source3/smbd/sec_ctx.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index c34247e6..5dda07e 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -331,11 +331,8 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct
 	TALLOC_FREE(ctx_p->token);
 
 	if (ngroups) {
-		ctx_p->ut.groups = (gid_t *)smb_memdup(groups,
-						       sizeof(gid_t) * ngroups);
-		if (!ctx_p->ut.groups) {
-			smb_panic("memdup failed");
-		}
+		ctx_p->ut.groups = (gid_t *)smb_xmemdup(groups,
+						        sizeof(gid_t) * ngroups);
 	} else {
 		ctx_p->ut.groups = NULL;
 	}
-- 
1.8.3.2


More information about the samba-technical mailing list