NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/52150: ipsec: kernel panic on adding a key with an invalid length

>Number:         52150
>Category:       kern
>Synopsis:       ipsec: kernel panic on adding a key with an invalid length
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 10 01:55:00 +0000 2017
>Originator:     Ryota Ozaki
>Release:        -current, -7 (and probably -6)
NetBSD kvm 7.99.67 NetBSD 7.99.67 (KVM) #870: Thu Apr  6 18:04:41 JST 2017  ozaki-r@rangeley:(hidden) amd64
Encryption types aes-gmac and aes-gcm-16 accept keys with lengths
160, 224 or 288 according to setkey(8). Adding a key with an
invalid length expects to fail with EINVAL or something, however,
instead the kernel gets panic.

This is an example output of a kernel panic:

kvm# setkey -c <<EOF
> add esp 10000 -E aes-gmac "hogehogehogehogehogehoge";
uvm_fault(0xfffffe8035304d10, 0x0, 1) -> e
fatal page fault in supervisor mode
trap type 6 code 0 rip 0xffffffff804c32e1 cs 0x8 rflags 0x10286 cr2 0 ilevel 0x4 rsp 0xfffffe8003764760
curlwp 0xfffffe803a564960 pid 73.1 lowest kstack 0xfffffe80037612c0
kernel: page fault trap, code=0
Stopped in pid 73.1 (setkey) at netbsd:esp_init+0x291:  movl    0(%r8),%eax
db{0}> bt
esp_init() at netbsd:esp_init+0x291
key_setsaval() at netbsd:key_setsaval+0x3b0
key_newsav.constprop.26() at netbsd:key_newsav.constprop.26+0xf8
key_add() at netbsd:key_add+0x2cc
key_parse() at netbsd:key_parse+0x725
key_output() at netbsd:key_output+0x162
key_send_wrapper() at netbsd:key_send_wrapper+0x6c
sosend() at netbsd:sosend+0x76f
do_sys_sendmsg_so() at netbsd:do_sys_sendmsg_so+0x272
do_sys_sendmsg() at netbsd:do_sys_sendmsg+0x85
sys_sendto() at netbsd:sys_sendto+0x5c
syscall() at netbsd:syscall+0x1ed
--- syscall (number 133) ---

Boot a kernel with IPSEC enabled and run the following command:
  setkey -c <<EOF
  add esp 10000 -E aes-gmac "hogehogehogehogehogehoge";

In esp_init, for aes-gmac and aes-gcm-16, sav->tdb_authalgxform is set
when the key length is valid but not set when invalid lengths. So later
accessing sav->tdb_authalgxform->type can cause a NULL pointer dereference.

diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index 4a577539dde..0a9dba81359 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -241,6 +241,10 @@ esp_init(struct secasvar *sav, const struct xformsw *xsp)
                        sav->alg_auth = SADB_X_AALG_AES256GMAC;
                        sav->tdb_authalgxform = &auth_hash_gmac_aes_256;
+               default:
+                       DPRINTF(("%s: invalid key length %u, must be either of "
+                           "20, 28 or 36\n", __func__, keylen));
+                       return EINVAL;
                memset(&cria, 0, sizeof(cria));
                cria.cri_alg = sav->tdb_authalgxform->type;

Home | Main Index | Thread Index | Old Index