Hello, 

I've found that after recstart of standby node of OpenBSD firewall cluster 
after sasyncd startup flows are synchronized from master but SAD's are not. 
I've investigated problem and found that this patch breaks this function: 

[ 
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h.diff?r1=1.89&r2=1.90&f=h
 | 
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h.diff?r1=1.89&r2=1.90&f=h
 ] 

And propably there is other patch that make this function not work properly. 
The reason is because during synchronization of states sasyncd aquiers states, 
encrypts almost-raw kernel message, send it to other sasyncd daemon where this 
message is decrypted and sent to kernel to set new states. Fortunetly kernel in 
function pfkeyv2_parsemessage() performs sanity checks of received from sasyncd 
message and finds out that it knows nothing about SADB_X_EXT_REPLAY extension 
end returns EINVAL and state is not created. I've added for tests part of code 
to allow this extension to pass sanity checks and then I've hit another 
extension that it is not allowed on message whitch is SADB_X_EXT_COUNTER. After 
adding this to parser function new states are created as they should be but i 
suppose that in some cases SADB_X_EXT_MTU extension also may be set and if so 
sasyncd silently will not create states either. 

please find out patch in attachment. 

How I discovered found error and solution? Following message that should create 
state is not valid according to the kernel: 

net_read: post decrypt 
0203000243000000000000000000000002000100cdc34e701001050c0402000004000200 
000000000000000000000000d2e3cd650000000000000000000000000400040000000000 
0000000000000000a80c0000000000000000000000000000040003000000000000000000 
00000000100e0000000000000000000000000000030005000000000010020000d45b18a6 
00000000000000000300060000000000100200000d3012d5000000000000000005000a00 
0100000000000000000000003231322e39312e32342e3136362f33320000000000000000 
04000b0001000000000000000000000031332e34382e31382e3231332f33320005000800 
000100005374b0606dc43282d401cf26ad15693c1336852981a56cd6c57c0098ef22dc51 
05000900000100002883b249a6964a07aa7f86571e70eb495e200fb692cff1434a78c49a 
05b14d38010014000102000001001300000000000300150000000000100200000a020f00 
0000000000000000030011000000000010020000ffffff00000000000000000003001600 
0000000010020000ac1f00000000000000000000030012000000000010020000fffff000 
000000000000000001001f00119400000200270000000000010000000000000009002400 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000008070605 
04030201 
net_read: computed hash 
1ee903f3fa270d5e55dafddf0f251e8230d080cc 
net_handle_messages: got msg type 1 len 536 from peer 172.31.255.245 
pfkey_queue_message: pfkey ADD len 536 seq 12 
sasyncd: pfkey: msg ADD write() failed on socket 4: Invalid argument 
net_read: got hash 

So I've enabled encdebug recompiled kernel, restarted it found following 
message related to this "Invalid argument" message: 

/bsd: pfkeyv2_parsemessage: extension header 39 not permitted on message type 3 

When I've added handling of SADB_X_EXT_REPLAY to the parser function and 
restarted the kernel states was still not created but this time following error 
was recorded: 

/bsd: pfkeyv2_parsemessage: extension header 36 not permitted on message type 3 

So I've added similar change for extension SADB_X_EXT_COUNTER too. I 
additionally see that in pfkeyv2.h in my version of OpenBSD (7.3) there is also 
SADB_X_EXT_MTU extension that will cause message parser fail if it will appear. 
Additionally in current there is also SADB_X_EXT_IFACE extension that that 
pfkeyv2_parsemessage is also unaware. 





Rafał Ramocki 
Technical Care Center 

        
        

E-mail:         [ mailto:rafal.ramo...@eo.pl | rafal.ramo...@eo.pl ] 


eo NETWORKS S.A.        NIP:    527-260-44-18   WWW:    [ https://eo.pl/ | 
eo.pl ] 
ul. Jagiellońska 78,    KRS:    0000332547      TEL:    (022) 532-15-30 
03-301 Warszawa         BDO:    000200011       FAX:    (022) 532-15-31 

Sąd Rejonowy dla m.st.. Warszawy w Warszawie XIII Wydział Gospodarczy Krajowego 
Rejestru Sądowego. Kapitał zakładowy i kapitał wpłacony: 205 937,90 złotych. 

Zapoznaj się z naszą polityką prywatności [ 
https://eo.pl/rodo/polityka-prywatnosci/ | tutaj ] 

Read our privacy policy [ https://eo.pl/en/gdpr/privacy-policy/ | here ] 

Index: net/pfkeyv2_parsemessage.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2_parsemessage.c,v
retrieving revision 1.60
diff -u -p -r1.60 pfkeyv2_parsemessage.c
--- net/pfkeyv2_parsemessage.c	14 Jul 2021 22:39:26 -0000	1.60
+++ net/pfkeyv2_parsemessage.c	16 Feb 2024 16:32:31 -0000
@@ -143,9 +143,9 @@ uint64_t sadb_exts_allowed_in[SADB_MAX+1
 	/* GETSPI */
 	BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
 	/* UPDATE */
-	BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
+	BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_REPLAY | BITMAP_X_COUNTER,
 	/* ADD */
-	BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
+	BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN | BITMAP_X_REPLAY | BITMAP_X_COUNTER,
 	/* DELETE */
 	BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN,
 	/* GET */
@@ -858,6 +858,19 @@ pfkeyv2_parsemessage(void *p, int len, v
 				return (EINVAL);
 			}
 			break;
+		case SADB_X_EXT_REPLAY:
+			if (i != sizeof(struct sadb_x_replay)) {
+				DPRINTF("bad REPLAY header length");
+				return (EINVAL);
+			}
+			break;
+		case SADB_X_EXT_COUNTER:
+			if (i != sizeof(struct sadb_x_counter)) {
+				DPRINTF("bad COUNTER header length");
+				return (EINVAL);
+			}
+			break;
+
 #if NPF > 0
 		case SADB_X_EXT_TAG:
 			if (i < sizeof(struct sadb_x_tag)) {

Reply via email to