diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2024-09-10 09:38:46 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2024-09-10 09:38:46 +0000 |
commit | ac03559eec9c9884aca86e9bec3adad306c61cad (patch) | |
tree | 36e373f8202a605a21b7e3564d6e901cf3cc4bde | |
parent | 130a57e6bd9a3c605515484079196ac3303cd26b (diff) |
Be more careful with aspath that have 0 length (aka the empty AS_PATH).
Again malloc(0) is not portable and calling memcpy with a NULL pointer
and a 0 length is not allowed by the C standard.
OK tb@
-rw-r--r-- | usr.sbin/bgpd/rde.c | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_attr.c | 23 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_sets.c | 5 |
3 files changed, 27 insertions, 7 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index fb58c5ec54d..4cd26fa6365 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.632 2024/09/09 15:00:45 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.633 2024/09/10 09:38:45 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -1123,7 +1123,9 @@ rde_dispatch_imsg_parent(struct imsgbuf *imsgbuf) sizeof(uint32_t)); break; case IMSG_RECONF_AS_SET_ITEMS: - if (imsg_get_ibuf(&imsg, &ibuf) == -1) + if (imsg_get_ibuf(&imsg, &ibuf) == -1 || + ibuf_size(&ibuf) == 0 || + ibuf_size(&ibuf) % sizeof(uint32_t) != 0) fatalx("IMSG_RECONF_AS_SET_ITEMS bad len"); nmemb = ibuf_size(&ibuf) / sizeof(uint32_t); if (set_add(last_as_set->set, ibuf_data(&ibuf), diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c index b1b4957475b..2d67efa829a 100644 --- a/usr.sbin/bgpd/rde_attr.c +++ b/usr.sbin/bgpd/rde_attr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_attr.c,v 1.134 2023/07/12 14:45:43 claudio Exp $ */ +/* $OpenBSD: rde_attr.c,v 1.135 2024/09/10 09:38:45 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -357,7 +357,8 @@ aspath_get(void *data, uint16_t len) aspath->len = len; aspath->ascnt = aspath_count(data, len); aspath->source_as = aspath_extract_origin(data, len); - memcpy(aspath->data, data, len); + if (len != 0) + memcpy(aspath->data, data, len); return (aspath); } @@ -396,7 +397,7 @@ aspath_put(struct aspath *aspath) u_char * aspath_deflate(u_char *data, uint16_t *len, int *flagnew) { - uint8_t *seg, *nseg, *ndata; + uint8_t *seg, *nseg, *ndata = NULL; uint32_t as; int i; uint16_t seg_size, olen, nlen; @@ -415,6 +416,9 @@ aspath_deflate(u_char *data, uint16_t *len, int *flagnew) fatalx("%s: would overflow", __func__); } + if (nlen == 0) + goto done; + if ((ndata = malloc(nlen)) == NULL) fatal("%s", __func__); @@ -437,6 +441,7 @@ aspath_deflate(u_char *data, uint16_t *len, int *flagnew) } } + done: *len = nlen; return (ndata); } @@ -791,6 +796,10 @@ aspath_prepend(struct aspath *asp, uint32_t as, int quantum, uint16_t *len) fatalx("aspath_prepend: preposterous prepend"); if (quantum == 0) { /* no change needed but return a copy */ + if (asp->len == 0) { + *len = 0; + return (NULL); + } p = malloc(asp->len); if (p == NULL) fatal("%s", __func__); @@ -834,7 +843,8 @@ aspath_prepend(struct aspath *asp, uint32_t as, int quantum, uint16_t *len) wpos += sizeof(uint32_t); } } - memcpy(p + wpos, asp->data + shift, asp->len - shift); + if (asp->len > shift) + memcpy(p + wpos, asp->data + shift, asp->len - shift); *len = l; return (p); @@ -852,6 +862,11 @@ aspath_override(struct aspath *asp, uint32_t neighbor_as, uint32_t local_as, uint16_t l, seg_size; uint8_t i, seg_len, seg_type; + if (asp->len == 0) { + *len = 0; + return (NULL); + } + p = malloc(asp->len); if (p == NULL) fatal("%s", __func__); diff --git a/usr.sbin/bgpd/rde_sets.c b/usr.sbin/bgpd/rde_sets.c index 766f38d3ade..bcfd858b21a 100644 --- a/usr.sbin/bgpd/rde_sets.c +++ b/usr.sbin/bgpd/rde_sets.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_sets.c,v 1.12 2022/07/28 13:11:51 deraadt Exp $ */ +/* $OpenBSD: rde_sets.c,v 1.13 2024/09/10 09:38:45 claudio Exp $ */ /* * Copyright (c) 2018 Claudio Jeker <claudio@openbsd.org> @@ -149,6 +149,9 @@ set_free(struct set_table *set) int set_add(struct set_table *set, void *elms, size_t nelms) { + if (nelms == 0) /* nothing todo */ + return 0; + if (set->max < nelms || set->max - nelms < set->nmemb) { uint32_t *s; size_t new_size; |