[Gluster-devel] gluster crashes in dht_getxattr_cbk() due to null pointer dereference.

Paul Guo bigpaulguo at foxmail.com
Fri May 8 09:55:01 UTC 2015


Hi,

gdb debugging shows the rootcause seems to be quite straightforward. The 
gluster version is 3.4.5 and the stack:

#0  0x00007eff735fe354 in dht_getxattr_cbk (frame=0x7eff775b6360, 
cookie=<value optimized out>, this=<value optimized out>, op_ret=<value 
optimized out>, op_errno=0,
     xattr=<value optimized out>, xdata=0x0) at dht-common.c:2043
2043	                DHT_STACK_UNWIND (getxattr, frame, local->op_ret, 
op_errno,
Missing separate debuginfos, use: debuginfo-install 
glibc-2.12-1.80.el6.x86_64 keyutils-libs-1.4-4.el6.x86_64 
krb5-libs-1.9-33.el6.x86_64 libcom_err-1.41.12-12.el6.x86_64 
libgcc-4.4.6-4.el6.x86_64 libselinux-2.0.94-5.3.el6.x86_64 
openssl-1.0.1e-16.el6_5.14.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x00007eff735fe354 in dht_getxattr_cbk (frame=0x7eff775b6360, 
cookie=<value optimized out>, this=<value optimized out>, op_ret=<value 
optimized out>, op_errno=0,
     xattr=<value optimized out>, xdata=0x0) at dht-common.c:2043
#1  0x00007eff7383c168 in afr_getxattr_cbk (frame=0x7eff7756ab58, 
cookie=<value optimized out>, this=<value optimized out>, op_ret=0, 
op_errno=0, dict=0x7eff76f21dc8, xdata=0x0)
     at afr-inode-read.c:618
#2  0x00007eff73aaaad8 in client3_3_getxattr_cbk (req=<value optimized 
out>, iov=<value optimized out>, count=<value optimized out>, 
myframe=0x7eff77554d4c) at client-rpc-fops.c:1115
#3  0x0000003de700d6f5 in rpc_clnt_handle_reply (clnt=0xc36ad0, 
pollin=0x14b21560) at rpc-clnt.c:771
#4  0x0000003de700ec6f in rpc_clnt_notify (trans=<value optimized out>, 
mydata=0xc36b00, event=<value optimized out>, data=<value optimized 
out>) at rpc-clnt.c:891
#5  0x0000003de700a4e8 in rpc_transport_notify (this=<value optimized 
out>, event=<value optimized out>, data=<value optimized out>) at 
rpc-transport.c:497
#6  0x00007eff74af6216 in socket_event_poll_in (this=0xc46530) at 
socket.c:2118
#7  0x00007eff74af7c3d in socket_event_handler (fd=<value optimized 
out>, idx=<value optimized out>, data=0xc46530, poll_in=1, poll_out=0, 
poll_err=0) at socket.c:2230
#8  0x0000003de785e907 in event_dispatch_epoll_handler 
(event_pool=0xb70e90) at event-epoll.c:384
#9  event_dispatch_epoll (event_pool=0xb70e90) at event-epoll.c:445
#10 0x0000000000406818 in main (argc=4, argv=0x7fff24878238) at 
glusterfsd.c:1934

See dht_getxattr_cbk() (below). When frame->local is equal to 0, gluster 
jumps to the label "out" where when it accesses local->xattr (i.e. 
0->xattr), it crashes. Note in 
DHT_STACK_UNWIND()->STACK_UNWIND_STRICT(), fn looks fine.

(gdb) p __local
$11 = (dht_local_t *) 0x0
(gdb) p frame->local
$12 = (void *) 0x0
(gdb) p fn
$1 = (fop_getxattr_cbk_t) 0x7eff7298c940 <mdc_readv_cbk>

I did not read the dht code much so I have not idea whether zero 
frame->local is normal or not, but from the code's perspective this is 
an obvious bug and it still exists in latest glusterfs workspace.

The following code change is a simple fix, but maybe there's a better one.
-        if (is_last_call (this_call_cnt)) {
+        if (is_last_call (this_call_cnt) && local != NULL) {

Similar issues exist in other functions also, e.g. stripe_getxattr_cbk() 
(I did not check all code).

int
dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                   int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
{
         int             this_call_cnt = 0;
         dht_local_t     *local = NULL;

         VALIDATE_OR_GOTO (frame, out);
         VALIDATE_OR_GOTO (frame->local, out);

         ......

out:
         if (is_last_call (this_call_cnt)) {
                 DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
                                   local->xattr, NULL);
         }
         return 0;
}




More information about the Gluster-devel mailing list