libreswan / libreswan

libreswan
https://libreswan.org/
Other
838 stars 220 forks source link

A possible null pointer dereferencein ikev1_quick.c #1172

Closed X1AOxiang closed 1 year ago

X1AOxiang commented 1 year ago

In ikev1 scenarios, when id type is configured as ipv4_addr, sending a quick mode packet with IDcr payload of type ID_FQDN (0x2) , may cause dereference of a null pointer in ikev1_quick.c : unsigned local_protocol = selector_protocol(*local_client)->ipproto;

cagney commented 1 year ago

Hi, which libreswan version, and would you have a full backtrace?

X1AOxiang commented 1 year ago

I found this problem in libreswan-4.11. Here is my config, the peer's config only switches the ip address:

conn mm_psk authby=secret ike=aes128-sha1;modp1536 keyexchange=ike ikev2=no phase2=esp compress=no pfs=no auto=add type=tunnel left=192.168.1.100 leftnexthop=%defaultroute right=192.168.1.101 rightnexthop=%defaultroute

The following is the pluto.log after receiving the fourth packet, before this, the IKE SA has been established through the main mode interaction.

Jun 19 17:54:54.425057: | received 156 bytes from 192.168.1.100:55703 on ens38 192.168.1.101:500 using UDP Jun 19 17:54:54.425107: | 1f ae 93 ca 7c 40 b9 a5 ff 34 3f 66 1d a1 a9 5d ....|@...4?f...] Jun 19 17:54:54.425111: | 08 10 20 01 d5 1b e5 98 00 00 00 9c 0e 89 11 c7 .. ............. Jun 19 17:54:54.425113: | b2 6d 30 20 bb 80 e5 98 92 70 4b f3 00 62 5d 2b .m0 .....pK..b]+ Jun 19 17:54:54.425115: | 11 e2 44 6e f2 b2 9d 23 eb d7 49 0d a4 d5 33 ac ..Dn...#..I...3. Jun 19 17:54:54.425117: | 8a bf 38 9f 35 c9 1f 76 df 97 43 f0 4a 83 8c ae ..8.5..v..C.J... Jun 19 17:54:54.425119: | bb 53 b1 f2 aa 98 e6 51 67 5f cc 79 92 54 47 ca .S.....Qg_.y.TG. Jun 19 17:54:54.425120: | fe 78 92 a2 cb e4 1b 8a 4a 8e 3b 76 91 ef 7f 9b .x......J.;v.... Jun 19 17:54:54.425122: | 97 2e a1 c3 52 e0 d7 af fa 7b 2d 4c 93 81 1f 17 ....R....{-L.... Jun 19 17:54:54.425124: | 5d dc da e2 58 47 0d dc 46 ba 8b b1 ef cf b8 90 ]...XG..F....... Jun 19 17:54:54.425126: | 1f eb 8c 24 d8 ea 99 ce c3 bb b7 16 ...$........ Jun 19 17:54:54.425130: | parse ISAKMP Message: Jun 19 17:54:54.425142: | initiator SPI: 1f ae 93 ca 7c 40 b9 a5 Jun 19 17:54:54.425146: | responder SPI: ff 34 3f 66 1d a1 a9 5d Jun 19 17:54:54.425148: | next payload type: ISAKMP_NEXT_HASH (0x8) Jun 19 17:54:54.425150: | ISAKMP version: ISAKMP Version 1.0 (rfc2407) (0x10) Jun 19 17:54:54.425152: | exchange type: ISAKMP_XCHG_QUICK (0x20) Jun 19 17:54:54.425165: | flags: ISAKMP_FLAG_v1_ENCRYPTION (0x1) Jun 19 17:54:54.425168: | Message ID: 3575375256 (d5 1b e5 98) Jun 19 17:54:54.425171: | length: 156 (00 00 00 9c) Jun 19 17:54:54.425173: | processing version=1.0 packet with exchange type=ISAKMP_XCHG_QUICK (32) Jun 19 17:54:54.425178: | State DB: IKEv1 state not found (find_state_ikev1) Jun 19 17:54:54.425180: | State DB: found IKEv1 state #1 in MAIN_R3 (find_state_ikev1) Jun 19 17:54:54.425203: | #1 is idle Jun 19 17:54:54.425205: | #1 idle Jun 19 17:54:54.425208: | received encrypted packet from 192.168.1.100:55703 Jun 19 17:54:54.425218: | got payload 0x100 (ISAKMP_NEXT_HASH) needed: 0x502 opt: 0x200030 Jun 19 17:54:54.425220: | parse ISAKMP Hash Payload: Jun 19 17:54:54.425223: | next payload type: ISAKMP_NEXT_SA (0x1) Jun 19 17:54:54.425225: | length: 24 (00 18) Jun 19 17:54:54.425228: | got payload 0x2 (ISAKMP_NEXT_SA) needed: 0x402 opt: 0x200030 Jun 19 17:54:54.425231: | parse ISAKMP Security Association Payload: Jun 19 17:54:54.425233: | next payload type: ISAKMP_NEXT_NONCE (0xa) Jun 19 17:54:54.425235: | length: 52 (00 34) Jun 19 17:54:54.425237: | DOI: ISAKMP_DOI_IPSEC (0x1) Jun 19 17:54:54.425239: | got payload 0x400 (ISAKMP_NEXT_NONCE) needed: 0x400 opt: 0x200030 Jun 19 17:54:54.425241: | parse ISAKMP Nonce Payload: Jun 19 17:54:54.425243: | next payload type: ISAKMP_NEXT_ID (0x5) Jun 19 17:54:54.425245: | length: 20 (00 14) Jun 19 17:54:54.425247: | got payload 0x20 (ISAKMP_NEXT_ID) needed: 0x0 opt: 0x200030 Jun 19 17:54:54.425261: | parse ISAKMP Identification Payload (IPsec DOI): Jun 19 17:54:54.425263: | next payload type: ISAKMP_NEXT_ID (0x5) Jun 19 17:54:54.425265: | length: 12 (00 0c) Jun 19 17:54:54.425267: | ID type: ID_IPV4_ADDR (0x1) Jun 19 17:54:54.425269: | Protocol ID: ALL (0x0) Jun 19 17:54:54.425272: | port: 0 (00 00) Jun 19 17:54:54.425274: | obj: Jun 19 17:54:54.425276: | c0 a8 01 64 ...d Jun 19 17:54:54.425278: | got payload 0x20 (ISAKMP_NEXT_ID) needed: 0x0 opt: 0x200030 Jun 19 17:54:54.425280: | parse ISAKMP Identification Payload (IPsec DOI): Jun 19 17:54:54.425282: | next payload type: ISAKMP_NEXT_NONE (0x0) Jun 19 17:54:54.425284: | length: 12 (00 0c) Jun 19 17:54:54.425286: | ID type: ID_FQDN (0x2) Jun 19 17:54:54.425288: | Protocol ID: ALL (0x0) Jun 19 17:54:54.425290: | port: 0 (00 00) Jun 19 17:54:54.425293: | obj: Jun 19 17:54:54.425295: | c0 a8 01 65 ...e Jun 19 17:54:54.425297: | removing 8 bytes of padding Jun 19 17:54:54.425314: | quick_inI1_outR1 HASH(1): Jun 19 17:54:54.425328: | 2f 6d b4 ad 88 88 d1 38 bb 16 52 80 7d cf 61 80 /m.....8..R.}.a. Jun 19 17:54:54.425333: | f8 9d 26 54 ..&T Jun 19 17:54:54.425335: | received 'quick_inI1_outR1' message HASH(1) data ok Jun 19 17:54:54.425340: | parsing 4 raw bytes of ISAKMP Identification Payload (IPsec DOI) into ID address Jun 19 17:54:54.425342: | ID address Jun 19 17:54:54.425344: | c0 a8 01 64 ...d Jun 19 17:54:54.425348: | peer client is 192.168.1.100/32 Jun 19 17:54:54.425352: "mm_test" #1: our client type is FQDN Jun 19 17:54:54.425356: "mm_test" #1: the peer proposed: Jun 19 17:54:54.425358: | find_v1_client_connection starting with mm_test Jun 19 17:54:54.425362: | looking for Jun 19 17:54:54.425365: | concrete checking against sr#0 192.168.1.101/32 -> 192.168.1.100/32 Jun 19 17:54:55.168585: | releasing whack fd@(nil) for (main() +1602 /programs/pluto/plutomain.c) Jun 19 17:54:55.168630: | delref fd@NULL (main() +1602 /programs/pluto/plutomain.c) Jun 19 17:54:55.168635: | delref fd@NULL (main() +1602 /programs/pluto/plutomain.c) ...

cagney commented 1 year ago

It looks like this:

            unsigned local_protocol = selector_protocol(*local_client)->ipproto;
            int local_port = selector_port(*local_client).hport;
            unsigned remote_protocol = selector_protocol(*remote_client)->ipproto;
            int remote_port = selector_port(*remote_client).hport;
            if (selector_range_eq_selector_range(spd->local->client, *local_client) &&
                selector_range_eq_selector_range(spd->remote->client, *remote_client) &&
                spd->local->client.ipproto == local_protocol &&
                (!spd->local->client.hport ||
                 spd->local->client.hport == local_port) &&
                (spd->remote->client.ipproto == remote_protocol) &&
                (!spd->remote->client.hport ||
                 spd->remote->client.hport == remote_port)) {

in find_v1_client_connection() (fc_try() has similar code)?

Since it's a FQDN local_client==unset_selector the entire loop should be skipped?

cagney commented 1 year ago

with the below

# /etc/ipsec.conf - Libreswan IPsec configuration file

config setup
    ikev1-policy=accept
    # put the logs in /tmp for the UMLs, so that we can operate
    # without syslogd, which seems to break on UMLs
    logfile=/tmp/pluto.log
    logtime=no
    logappend=no
    plutodebug=all
    dumpdir=/tmp

conn %default
     #keyexchange=ikev1
     ikev2=no
     authby=secret
     ike=aes128-sha1;modp1536
     phase2=esp
     compress=no
     pfs=no
     auto=add
     type=tunnel
     left=192.1.2.45
     right=192.1.2.23
     leftsubnet=192.0.1.0/24
     rightsubnet=192.0.2.0/24

conn east

conn west
     #leftid=192.1.2.45
     #rightid=192.1.2.23

quick mode will send two "ISAKMP Identification Payload" payloads; now to make one of them FQDN

cagney commented 1 year ago

fixed in 4.12 and mainline; thanks!