Bug 590783

Summary: Racoon daemon blocks on recv() call due to empty pfkey socket
Product: Red Hat Enterprise Linux 5 Reporter: Issue Tracker <tao>
Component: ipsec-toolsAssignee: Tomas Mraz <tmraz>
Status: CLOSED CURRENTRELEASE QA Contact: Ondrej Moriš <omoris>
Severity: urgent Docs Contact:
Priority: urgent    
Version: 5.3CC: cward, ebenes, joey, jrieden, jwest, lmiksik, omoris, plyons, tao, vincew
Target Milestone: rcKeywords: OtherQA, ZStream
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: ipsec-tools-0.6.5-14.el5.3 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-10-02 10:55:03 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 609090    
Attachments:
Description Flags
patch customer reports success with (uses pfkey_open instead of privsep_socket since it is not present in 0.6.5) none

Description Issue Tracker 2010-05-10 17:28:46 UTC
Escalated to Bugzilla from IssueTracker

Comment 1 Issue Tracker 2010-05-10 17:28:47 UTC
Event posted on 04-15-2010 10:07am EDT by kolotov

Description of problem:

Racoon daemon stops responding for ~2 minutes. 
At this time it is not responding to DPD from far end
(just nothing in logs at all like it fall to forever
loop or waiting in sys call, etc...).

How reproducible: Always reproducible under traffic

Steps to Reproduce:

Set IKE phase 1 lifetime to 10 minutes and phase 2 lifetime 
to 3 minutes (problem can be duped with any lifetimes, small 
one is just make it easy) for near end and far end.

It was reproduced during testing of high call traffic between
telephony servers.

Actual results:

As described.

Expected results:

Racoon should not die or stuck for some time.

Additional info:

Attached:
1. sos report files
2. racoon debug logs from this server, issue time in log is 20:17
This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 2 Issue Tracker 2010-05-10 17:28:49 UTC
Event posted on 04-26-2010 06:57am EDT by kolotov

In addition to previous note, it seems that there are 2 cases when handling
isakmp delete payload (I'm referring to base_others.log, Apr 21 test):

Code flow:

session
  select(...)
  admin_handler
  ...
  isakmp_handler
    isakmp_main
      isakmp_info_recv
        isakmp_info_recv_d
          purge_ipsec_spi
            pfkey_dump_sadb
              pfkey_send_dump
              ...
              while(1)
                pk_recv(pfkey_socket)
          ...
          if (spi in packet is same as spi in db)
            pfkey_send_delete          
  ...
  pfkey_handler
    pk_recv(pfkey_socket)
      recv                                      <--- we stuck here
      
1. Good case:

Apr 21 12:50:08 altnrs racoon: DEBUG: seen nptype=8(hash)
Apr 21 12:50:08 altnrs racoon: DEBUG: seen nptype=12(delete)
Apr 21 12:50:08 altnrs racoon: DEBUG: succeed.
Apr 21 12:50:08 altnrs racoon: DEBUG: call pfkey_send_dump
Apr 21 12:50:08 altnrs racoon: DEBUG: check spi(packet)=1576530486
spi(db)=4010845127.
Apr 21 12:50:08 altnrs racoon: DEBUG: check spi(packet)=1576530486
spi(db)=1576530486.
Apr 21 12:50:08 altnrs racoon: DEBUG: an undead schedule has been
deleted.
Apr 21 12:50:08 altnrs racoon: INFO: purged IPsec-SA proto_id=ESP
spi=1576530486.
Apr 21 12:50:08 altnrs racoon: DEBUG: purged SAs.
Apr 21 12:50:08 altnrs racoon: DEBUG: get pfkey DELETE message

In good case, SPI is found in db and pfkey delete message is sent to
pfkey_socket, no gaps.

2. Bad case:

Apr 21 12:35:20 altnrs racoon: DEBUG: seen nptype=8(hash)
Apr 21 12:35:20 altnrs racoon: DEBUG: seen nptype=12(delete)
Apr 21 12:35:20 altnrs racoon: DEBUG: succeed.
Apr 21 12:35:20 altnrs racoon: DEBUG: Cannot record event: event queue
overflowed
Apr 21 12:35:20 altnrs racoon: DEBUG: call pfkey_send_dump
Apr 21 12:35:20 altnrs racoon: DEBUG: check spi(packet)=3445397493
spi(db)=2058958942.
Apr 21 12:35:20 altnrs racoon: DEBUG: purged SAs.

<gap, 2 minutes>

Apr 21 12:37:42 altnrs racoon: DEBUG: get pfkey ACQUIRE message

In bad case, spi is not found in db. So we drain all data from
pfkey_socket in pfkey_dump_sadb() in while(1) loop. When we leave this
function pfkey_socket contains no data. But after that we immediately go
to pfkey_handler and trying to get data from it. Since it contains nothing
and no timeout is set - we wait forever until ANY message comes to us (for
instance ACQUIRE like in logs above).

Difference against good case is that in good case pfkey delete message is
put to socket, so when we try recv() inside pfkey_handler(), we have data
to receive. 

Problem here is that pfkey_handler() seems to be written basing on
assuption that it is called after select(), we sure that there is some
data in the socket, so we make blocking sys call recv() to get this data.
Btw, gdb backtrace also shows that there is 0 bytes in socket
(sadb_msg_len = 0):

#0  0x00560f2c in recv () from /lib/libc.so.6
No symbol table info available.
#1  0x00b4b19e in pk_recv (so=5, lenp=0xba7ff4) at pfkey.c:3032
       buf = {sadb_msg_version = 10 '\n', sadb_msg_type = 125 '}',
sadb_msg_errno = 254 '?', sadb_msg_satype = 11 '\v', sadb_msg_len =
0, 
  sadb_msg_reserved = 0, sadb_msg_seq = 0, sadb_msg_pid = 152615312}



Could you please provide your view on this? 


This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 3 Issue Tracker 2010-05-10 17:28:50 UTC
Event posted on 04-29-2010 06:20am EDT by kolotov

I don't think it is correct to say that FD_ISSET will return true only if
there is data in socket. This macros is just checking that specified fd is
in fd_set and it's status is ready to recieve, all this is set inside
select() (something like that).

Only select() call gives answer if there is some data in socket or not. 

Review my analysis one more time, issue happens like:
1. select() called from session() determines that there is data to receive
in admin socket, isakmp socket and pfkey socket
2. handlers are called in turn from session()
3. isakmp_handler() reads data from isakmp socket, handles request. If
this is request to delete spi, pfkey sadb dump request is sent to kernel
to get list of spi's we have. This list is put by kernel to
***pkfey_socket***. After that we read all data from pfkey_socket. If no
such spi in the list, we just return back to session()
4. pfkey_handler() called immediately after that from session(). FD_ISSET
check can't help at all, because fd_set structure was updated by select()
only before isakmp_handler(). And it is not updated after isakmp_handler()
drain all data from pfkey_socket.
5. pfkey_handler() calls pk_recv() and waits for any message to
pfkey_socket forever.

Hope this is now clear enough.


This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 4 Issue Tracker 2010-05-10 17:28:51 UTC
Event posted on 04-30-2010 07:43am EDT by kolotov

I've already tried calling pfkey_handler() before isakmp_handler() - and
this fixes issue with racoon hang, I didn't find any delays in logs. This
looks much better than setting timeout for socket.

But you are right saying that isakmp_handler() ideally shouldn't touch
pfkey_socket at all, because if both sockets has data in them after
select(), isakmp_handler() can get not only sadb dump from pfkey_socket,
but other important messages. This can be potential cause of data
corruption. 

I have one more question, about how racoon should act if it receives
notification from far end to delete old phase1 sa? This is handled in
purge_remote(). Currently racoon is deleting old phase 1 sa and also all
associated phase 2 sa's. I'm wondering to know if this is expected
behavior. I.e. why not leaving phase 2 sa's, kernel will remove them ones
they expire...

Can you provide any advice on this?

Thanks.


This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 5 Issue Tracker 2010-05-10 17:28:53 UTC
Event posted on 05-04-2010 10:49am EDT by vincew

Posting Tomas' email reply so we have it in the ticket:
------------------------------
On Mon, 2010-05-03 at 16:43 -0400, Vince Worthington wrote: 
> > Hi Tomas,
> > 
> > Scott Mayhew had an idea about that racoon issue we chatted about last

> > week.  The one where isakmp_handler was draining the pfkey socket that

> > leads to a blocking recv() call because select() is not getting called

> > again before the FD_ISSET() check for pfkey_handler.
> > 
> > (Also, switching the order of isakmp_handler and pfkey_handler
FD_ISSET 
> > checks like you suggested does seem to work OK also).
> > 
> > Scott's idea was, why don't we just do a non-blocking, "peek"
receive 
> > (ie, recv() with MSG_DONTWAIT|MSG_PEEK flags) on the pfkey socket and

> > test for a positive number of bytes returned, before we do FD_ISSET 
> > again and call pfkey_handler?  ie, see if there is still anything to 
> > receive on the socket before we call pfkey_handler and end up with a 
> > blocking recv() when the socket is drained?
> > 
> > I looked at the code doing recv* calls in the handler function chains

> > and they appear to make liberal use of MSG_PEEK's also, so it
doesn't 
> > seem to really go against how it is coded elsewhere - except that with

> > MSG_DONTWAIT we can find out whether a non-peek recv would block or
not 
> > (no data waiting) and avoid calling pfkey_handler at all.
> > 
> > I put a patch together and am wondering what your opinion of it would

> > be.  We've done some basic testing and it appears to work OK, but we

> > have still not heard back from the customer who we believe is also 
> > testing it.

This is really questionable. The main problem is that if the order of
the isakmp_handler and pfkey_handler is as is currently the race that
causes the blocking recv() causes also some events from pfkey to be
lost. Switching the order of the calls might help in this case although
it does not eliminate the race completely, it just makes it much less
likely to appear and the outcome of the race should never be the
blocking recv(), only some event can be lost.

I would really like to see how would long testing of this solution
worked out.

-- Tomas Mraz
No matter how far down the wrong road you've gone, turn back. Turkish
proverb 
------------------------------


This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 6 Issue Tracker 2010-05-10 17:28:54 UTC
Event posted on 05-06-2010 01:23pm EDT by vincew

vw7 build:

http://brewweb.devel.redhat.com/brew/taskinfo?taskID=2425875

vw7 build has noopt compile + patch attached

As Tomas mentioned, we *should* be able to test whether the change this
upstream-like patch helps the problem.  They (best I can tell) appear to
NOT be using privilege separation (ie they are running racoon as root) so
it should be OK to call pfkey_sock instead as this patch does.

If this helps them, it is probably going to mean we have more patching to
do but at least it will tell us we are moving in the right direction.

Also for the sake of getting this documented in the case, this the
upstream patch Tomas recommended:

http://cvsweb.netbsd.org/bsdweb.cgi/src/crypto/dist/ipsec-tools/src/racoon/pfkey.c.diff?r1=1.38&r2=1.39

although 0.6.5 doesn't have a privsep_socket() function, so further
patchwork may be required.

Thanks,
Vince


This event sent from IssueTracker by vincew  [SEG - Base OS]
 issue 767803

Comment 7 Tomas Mraz 2010-05-10 17:51:31 UTC
(In reply to comment #4)
> Event posted on 04-30-2010 07:43am EDT by kolotov

> I have one more question, about how racoon should act if it receives
> notification from far end to delete old phase1 sa? This is handled in
> purge_remote(). Currently racoon is deleting old phase 1 sa and also all
> associated phase 2 sa's. I'm wondering to know if this is expected
> behavior. I.e. why not leaving phase 2 sa's, kernel will remove them ones
> they expire...
> 
> Can you provide any advice on this?

The removing of SA on notification from far end might be changed in upstream CVS in a way similar to what is suggested here. But I am slightly afraid of changing this as it might in some circumstances mean that the phase 2 SA data would not be properly deleted in racoon daemon and this would result in a memory leak.

Comment 9 Vince Worthington 2010-06-01 19:56:20 UTC
Created attachment 418794 [details]
patch customer reports success with (uses pfkey_open instead of privsep_socket since it is not present in 0.6.5)

Comment 11 Issue Tracker 2010-06-02 14:35:39 UTC
Event posted on 06-02-2010 10:35am EDT by vincew

Scott if you wouldn't mind, can you file an accelerated fix request for
this case?  Here's (I think) our most current process doc on it:

http://intranet.corp.redhat.com/ic/intranet/HotFix

If you would, flip this back to WoSEG once the request is filed and I'll
escalate it to SEG TL so Jeremy can engage ENG on it.

PS:  Note that while customer has verified the concept patch we still need
the privsep_socket function the actual upstream patch uses.

Thanks
Vince

Internal Status set to 'Waiting on Support'

This event sent from IssueTracker by vincew 
 issue 767803

Comment 19 Tomas Mraz 2010-06-28 15:55:12 UTC
*** Bug 599071 has been marked as a duplicate of this bug. ***

Comment 25 Vince Worthington 2010-12-02 17:06:02 UTC
Feedback from customer was positive.

Also, for future reference purposes, this was the gdb backtrace:

(gdb) bt
#0  0x00560f2c in recv () from /lib/libc.so.6
#1  0x00b4b19e in pk_recv (so=5, lenp=0xba7ff4) at pfkey.c:3032
#2  0x00b4b691 in pfkey_handler () at pfkey.c:204
#3  0x00b2a6a2 in session () at session.c:215
#4  0x00b2995e in main (ac=5, av=0xbfb9b02c) at main.c:253

(we've since had a similar case raised by another customer who believed it might be the same bug but the backtrace was different)

--vince

Comment 26 Joe Pruett 2011-05-11 22:13:01 UTC
is there any update to this?  this bug bites me on a regular basis.

Comment 27 Tomas Mraz 2011-05-12 06:05:41 UTC
(In reply to comment #26)
> is there any update to this?  this bug bites me on a regular basis.

What ipsec-tools rpm package version do you have?

Comment 28 Joe Pruett 2011-05-12 15:25:45 UTC
my version ipsec-tools-0.6.5-14.el5_5.5

Comment 29 Tomas Mraz 2011-05-12 18:28:01 UTC
Then this is a different bug as the version you have uses a separate socket for the pfkey sadb dumps.

Please use the regular support channels http://www.redhat.com/support to report the issue. Thank you.