s3: libsmbclient: After getting attribute server, ensure main srv pointer is still...
authorJeremy Allison <jra@samba.org>
Tue, 31 Mar 2015 21:40:23 +0000 (14:40 -0700)
committerDavid Disseldorp <ddiss@samba.org>
Tue, 14 Apr 2015 00:58:43 +0000 (02:58 +0200)
Bug #11186: Crash seen in libsmbclient due to free of server structure during SMBC_getxattr() call

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11186

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Autobuild-User(master): David Disseldorp <ddiss@samba.org>
Autobuild-Date(master): Tue Apr 14 02:58:43 CEST 2015 on sn-devel-104

source3/libsmb/libsmb_xattr.c

index 84937766fe2ba1f371e6e7a5322fbaf3ca5e84b3..9f7bea8da11b0e6c5d64ad80d6920a57b2e8ec17 100644 (file)
@@ -2073,6 +2073,25 @@ SMBC_getxattr_ctx(SMBCCTX *context,
         if (! srv->no_nt_session) {
                 ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
         if (! srv->no_nt_session) {
                 ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
+               /*
+                * SMBC_attr_server() can cause the original
+                * server to be removed from the cache.
+                * If so we must error out here as the srv
+                * pointer has been freed.
+                */
+               if (smbc_getFunctionGetCachedServer(context)(context,
+                               server,
+                               share,
+                               workgroup,
+                               user) != srv) {
+#if defined(ECONNRESET)
+                       errno = ECONNRESET;
+#else
+                       errno = ETIMEDOUT;
+#endif
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
                 if (! ipc_srv) {
                         srv->no_nt_session = True;
                 }
                 if (! ipc_srv) {
                         srv->no_nt_session = True;
                 }
@@ -2208,9 +2227,31 @@ SMBC_removexattr_ctx(SMBCCTX *context,
         }
 
         if (! srv->no_nt_session) {
         }
 
         if (! srv->no_nt_session) {
+               int saved_errno;
                 ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
                 ipc_srv = SMBC_attr_server(frame, context, server, port, share,
                                            &workgroup, &user, &password);
+               saved_errno = errno;
+               /*
+                * SMBC_attr_server() can cause the original
+                * server to be removed from the cache.
+                * If so we must error out here as the srv
+                * pointer has been freed.
+                */
+               if (smbc_getFunctionGetCachedServer(context)(context,
+                               server,
+                               share,
+                               workgroup,
+                               user) != srv) {
+#if defined(ECONNRESET)
+                       errno = ECONNRESET;
+#else
+                       errno = ETIMEDOUT;
+#endif
+                       TALLOC_FREE(frame);
+                       return -1;
+               }
                 if (! ipc_srv) {
                 if (! ipc_srv) {
+                       errno = saved_errno;
                         srv->no_nt_session = True;
                 }
         } else {
                         srv->no_nt_session = True;
                 }
         } else {