Bug#855869: dsniff: segfaults on portmapper messages
Package: dsniff
Version: 2.4b1+debian-23
Severity: important
Hi,
dsniff segfaults when receiving any RPC portmapper messages.
To generate such messages, I used:
rpcinfo -l <hostname of server with NFS running> 100021 4
But I expect any rpcinfo -l command will cause this to happen.
> Program received signal SIGSEGV, Segmentation fault.
> __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:294
> 294 ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
> (gdb) bt full
> #0 __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:294
> No locals.
> #1 0x00007ffff655ce24 in _IO_new_file_xsputn (f=0x7fffffffe0f0, data=0x555555797bd4, n=140737326206416) at fileops.c:1327
> s = 0x555555797bd4 ""
> to_do = 140737326206416
> n = 140737326206416
> data = 0x555555797bd4
> f = 0x7fffffffe0f0
> s = 0x555555797bd4 ""
> to_do = 140737326206416
> #2 0x000055555555983e in rpc_decode (buf=buf at entry=0x555555797bd0 "6]T\275", len=88, len at entry=92, msg=msg at entry=0x7fffffffe1c0) at ./rpc.c:129
> xdrs = {x_op = (unknown: 4136102144), x_ops = 0x7ffff687f440 <_IO_file_jumps>, x_public = 0x7ffff68835a3 <_IO_2_1_stderr_+131> "\n",
> x_private = 0x7ffff655bb32 <new_do_write+98> "H\205\300H\211\305\017\267\273\200", x_base = 0x2525252525252525 <error: Cannot access memory at address 0x2525252525252525>, x_handy = 1}
> fraghdr = <optimized out>
> p = 0x555555797bd4 ""
> tmp = <optimized out>
> stat = 0
> tmplen = <optimized out>
> #3 0x000055555555ec71 in decode_portmap (buf=0x555555797bd0 "6]T\275", len=92, obuf=<optimized out>, olen=<optimized out>) at ./decode_portmap.c:35
> xdrs = {x_op = (unknown: 4294959712), x_ops = 0x7fffffffe1a0, x_public = 0x6f00000063 <error: Cannot access memory at address 0x6f00000063>,
> x_private = 0x6f <error: Cannot access memory at address 0x6f>, x_base = 0x5555555617df "portmap", x_handy = 1}
> msg = {rm_xid = 0, rm_direction = CALL, ru = {RM_cmb = {cb_rpcvers = 0, cb_prog = 0, cb_vers = 0, cb_proc = 0, cb_cred = {oa_flavor = 0, oa_base = 0x0, oa_length = 0}, cb_verf = {oa_flavor = 0,
> oa_base = 0x0, oa_length = 0}}, RM_rmb = {rp_stat = MSG_ACCEPTED, ru = {RP_ar = {ar_verf = {oa_flavor = 0, oa_base = 0x0, oa_length = 0}, ar_stat = SUCCESS, ru = {AR_versions = {low = 0,
> high = 0}, AR_results = {where = 0x0, proc = 0x0}}}, RP_dr = {rj_stat = RPC_MISMATCH, ru = {RJ_versions = {low = 0, high = 0}, RJ_why = AUTH_OK}}}}}}
> pm = <optimized out>
> pmap = {pm_prog = 93824994606032, pm_vers = 140737326678332, pm_prot = 64, pm_port = 206158430232}
> xm = <optimized out>
> hdrlen = <optimized out>
> #4 0x000055555555a524 in trigger_tcp_half (addr=addr at entry=0x7ffff7fa0010, hs=hs at entry=0x7ffff7fa0088, t=0x55555577f470 <tcp_triggers+656>) at ./trigger.c:377
> buf = 0x555555797bd0 "6]T\275"
> len = 92
> #5 0x000055555555afaa in trigger_tcp (ts=0x7ffff7fa0010, conn_save=<optimized out>) at ./trigger.c:430
> tr = <optimized out>
> #6 0x00007ffff77a7f68 in process_tcp () from /usr/lib/libnids.so.1.21
> No symbol table info available.
> #7 0x00007ffff77a5f35 in ?? () from /usr/lib/libnids.so.1.21
> No symbol table info available.
> #8 0x00007ffff77a60ae in ?? () from /usr/lib/libnids.so.1.21
> No symbol table info available.
> #9 0x00007ffff77a621b in nids_pcap_handler () from /usr/lib/libnids.so.1.21
> No symbol table info available.
> #10 0x00007ffff7565646 in ?? () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
> No symbol table info available.
> #11 0x00007ffff75662d7 in ?? () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
> No symbol table info available.
> #12 0x00007ffff756e26d in pcap_loop () from /usr/lib/x86_64-linux-gnu/libpcap.so.0.8
> No symbol table info available.
> #13 0x00007ffff77a58f6 in nids_run () from /usr/lib/libnids.so.1.21
> No symbol table info available.
> #14 0x0000555555556dc3 in main (argc=<optimized out>, argv=<optimized out>) at ./dsniff.c:269
> services = 0x555555561958 "/usr/share/dsniff/dsniff.services"
> savefile = 0x0
> triggers = 0x0
> c = <optimized out>
A few things I notice looking at rpc_decode...
> int
> rpc_decode(u_char *buf, int len, struct rpc_msg *msg)
> {
[...]
> /* Decode RPC message. */
> memset(msg, 0, sizeof(*msg));
>
> if (ntohl(((struct rpc_msg *)buf)->rm_direction) == CALL) {
This:
- Almost certainly breaks the strict aliasing rule and is thus undefined
behavior.
- Will fail on 64-bit systems since struct rpc_msg::xid is 64-bits, but
the RPC xid field in buf is only 32-bits.
- I expect the check for REPLY below fails on big-endian systems.
> xdrmem_create(&xdrs, buf, len, XDR_DECODE);
>
> if (!xdr_callmsg(&xdrs, msg)) {
> xdr_destroy(&xdrs);
> return (0);
> }
> }
> else if (ntohl(((struct rpc_msg *)buf)->rm_direction) == REPLY) {
> msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
> xdrmem_create(&xdrs, buf, len, XDR_DECODE);
>
> if (!xdr_replymsg(&xdrs, msg)) {
> xdr_destroy(&xdrs);
> return (0);
> }
> }
> stat = xdr_getpos(&xdrs);
> xdr_destroy(&xdrs);
Both these calls try to read / free garbage memory if both if statements
above fail.
Thanks,
James
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-security-team/attachments/20170222/dea0fe92/attachment.sig>
Reply to: