[Openswan dev] free_sa() crasher with LEAK_DETECTIVE, could use another eye ball

Paul Wouters paul at xelerance.com
Tue Jul 12 13:05:21 EDT 2011


If you compile with LEAK_DETECTIVE=yes and use compress=yes in your conn, we crash on what
looks like a double pfree()

(gdb) bt
#0  0x00007f31498d4945 in raise (sig=6)
     at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007f31498d6125 in abort () at abort.c:92
#2  0x00007f314b95d6c2 in openswan_log_abort (
     file_str=0x7f314ba30ba0 "/builddir/build/BUILD/openswan-2.6.34/lib/libopenswan/alloc.c", line_no=138)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/log.c:536
#3  0x00007f314b95da53 in passert_fail (
     pred_str=0x7f314ba30c0e "p->i.magic == LEAK_MAGIC",
     file_str=0x7f314ba30ba0 "/builddir/build/BUILD/openswan-2.6.34/lib/libopenswan/alloc.c", line_no=138)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/log.c:636
#4  0x00007f314b9e544e in leak_pfree (ptr=0x7f3144b2afe8, leak=1)
     at /usr/src/debug/openswan-2.6.34/lib/libopenswan/alloc.c:138
#5  0x00007f314b9b1db1 in free_sa_prop (dp=0x7f3144b2cfe8)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/spdb.c:989
#6  0x00007f314b9b1e76 in free_sa_prop_conj (pc=0x7f3144ad9ff0)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/spdb.c:1012
#7  0x00007f314b9b1f58 in free_sa (f=0x7f3144ad7fd8)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/spdb.c:1038
#8  0x00007f314b9b3d8a in out_sa (outs=0x7fff91f7a6c0, sadb=0x7f3144ad7fd8,
     st=0x7f3144cdb888, oakley_mode=0, aggressive_mode=0, np=10 '\n')
     at /usr/src/debug/openswan-2.6.34/programs/pluto/spdb_v1_struct.c:509
---Type <return> to continue, or q <return> to quit---
#9  0x00007f314b97d89b in quick_outI1_tail (pcrc=0x7f3144ad3f60,
     r=0x7fff91f7a870)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1_quick.c:905
#10 0x00007f314b97cffe in quick_outI1_continue (pcrc=0x7f3144ad3f60,
     r=0x7fff91f7a870, ugh=0x0)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1_quick.c:735
#11 0x00007f314b9a8399 in send_crypto_helper_request (r=0x7fff91f7a870,
     cn=0x7f3144ad3f60, toomuch=0x7fff91f7a86c)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/pluto_crypt.c:416
#12 0x00007f314b9aa34e in build_ke (cn=0x7f3144ad3f60, st=0x7f3144cdb888,
     group=0x7f314bc51ae0, importance=pcim_demand_crypto)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/crypt_ke.c:211
#13 0x00007f314b97d4e3 in quick_outI1 (whack_sock=-1,
     isakmp_sa=0x7f3144db9888, c=0x7f31458dcbb8, policy=2181103734, try=1,
     replacing=0)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1_quick.c:828
#14 0x00007f314b9595a6 in unpend (st=0x7f3144db9888)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/pending.c:197
#15 0x00007f314b9738d8 in complete_v1_state_transition (mdp=0x7f314bc5be88,
     result=STF_OK)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1.c:2303
#16 0x00007f314b972233 in process_packet_tail (mdp=0x7f314bc5be88)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1.c:1855
---Type <return> to continue, or q <return> to quit---
#17 0x00007f314b971177 in process_v1_packet (mdp=0x7f314bc5be88)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/ikev1.c:1397
#18 0x00007f314b9a219b in process_packet (mdp=0x7f314bc5be88)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/demux.c:163
#19 0x00007f314b9a2227 in comm_handle (ifp=0x7f3144d8dfc0)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/demux.c:212
#20 0x00007f314b968357 in call_server ()
     at /usr/src/debug/openswan-2.6.34/programs/pluto/server.c:764
#21 0x00007f314b964e79 in main (argc=13, argv=0x7fff91f7c498)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/plutomain.c:1055
(gdb) f 5
#5  0x00007f314b9b1db1 in free_sa_prop (dp=0x7f3144b2cfe8)
     at /usr/src/debug/openswan-2.6.34/programs/pluto/spdb.c:989
989		pfree(dp->trans);
(gdb) p dp->trans
$4 = (struct db_trans *) 0x7f3144b2afe8
(gdb) p *dp->trans
$5 = {transid = 2, attrs = 0x0, attr_cnt = 0}
(gdb) f 4
#4  0x00007f314b9e544e in leak_pfree (ptr=0x7f3144b2afe8, leak=1)
     at /usr/src/debug/openswan-2.6.34/lib/libopenswan/alloc.c:138
138		passert(p->i.magic == LEAK_MAGIC);
(gdb) p p
$6 = (union mhdr *) 0x7f3144b2afc0
(gdb) p *p
$7 = {i = {name = 0x0, older = 0x0, newer = 0x0, magic = 0, size = 0},
   junk = 0}


This is not a double pfree() because the magic should then be !LEAK_MAGIC,
while it is 0. (It could be a free() though that's untracked)

Linking with efence showed that we did not scribble over the end of
a variable, because it never got triggered. Setting EF_PROTECT_BELOW=1
also showed we did not scribble over the beginning. I also tested with
EF_PROTECT_FREE=1.

Looking at the code:

void
free_sa(struct db_sa *f)
{
     unsigned int i;
     if(f == NULL) return;

     for(i=0; i<f->prop_conj_cnt; i++) {
         free_sa_prop_conj(&f->prop_conjs[i]);
     }
     if(f->prop_conjs) {
         pfree(f->prop_conjs);
         f->prop_conjs=NULL;
         f->prop_conj_cnt=0;
     }
[...]

free_sa calls free_sa_prop_conj():

void
free_sa_prop_conj(struct db_prop_conj *pc)
{
     unsigned int i;
     for(i=0; i<pc->prop_cnt; i++) {
         free_sa_prop(&pc->props[i]);
     }
     if(pc->props) {
         pfree(pc->props);
     }
}

which loops over free_sa_prop():

void
free_sa_prop(struct db_prop *dp)
{
     unsigned int i;
     for(i=0; i<dp->trans_cnt; i++) {
         free_sa_trans(&dp->trans[i]);
     }
     if(dp->trans) {
         pfree(dp->trans);     <---- this is the bad pfree
         dp->trans=NULL;
     }
}

which loops over free_sa_trans():

void
free_sa_trans(struct db_trans *tr)
{
     if(tr->attrs) {
         pfree(tr->attrs);
         tr->attrs=NULL;
     }
}

The crash happens in the pfree() in free_sa_prop()

I then tried to use EF_FILL=1 and reran:

then I got:

(gdb) f 4
#4  0x0000000000486d47 in leak_pfree (ptr=0xb02310, leak=1)
     at /root/openswan-2.6.35dr1/lib/libopenswan/alloc.c:138
138		passert(p->i.magic == LEAK_MAGIC);
(gdb) p p 
$1 = (union mhdr *) 0xb022e8
(gdb) p *p 
$2 = {i = {
     name = 0xdb0be6ec813a0a35 <Address 0xdb0be6ec813a0a35 out of bounds>,
     older = 0x779b8b6d8d22cf2a, newer = 0x180000142e17ed1b,
     magic = 16044425180566980584, size = 49}, junk = 15783963222504770101}

and using EF_FILL=254:

(gdb) p *p
$1 = {i = {name = 0x1a6ed58 "\002", older = 0x1a6bda8, newer = 0x0, magic = 0,
     size = 33}, junk = 27716952}

I tried without setting EF_FILL and also got different values, but magic =0.
I am not sure if this is LEAK_DETECTIVE and efence fighting?

When not using LEAK_DETECTIVE and only efence, I get no crasher, with or withut
EF_PROTECT_BELOW set.....

So I'm left somewhat confused,

Paul



More information about the Dev mailing list