summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2018-04-02 19:25:34 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2018-04-02 19:25:34 +0000
commit0b6e96a27621020d53ee9d97ec6de9ec38407e05 (patch)
tree3abbf044ac66c7bbb0f11d9e7708dcf43792f73f /usr.sbin
parent9d359c32344e784a360f823a2ff4f95019160766 (diff)
aspath_verify() can not call aspath_extract() since this function only works
on 4-byte AS path. Since this function is also called with 2-byte ASPATH attributes. Instead inline the check using the as_size. Problem found by Tom Beard (tom at exilien.uk), thanks for the report OK job@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/rde_attr.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c
index c53c211ef79..f18e2d559a8 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.100 2017/05/31 10:44:00 claudio Exp $ */
+/* $OpenBSD: rde_attr.c,v 1.101 2018/04/02 19:25:33 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -426,7 +426,7 @@ aspath_verify(void *data, u_int16_t len, int as4byte)
u_int8_t *seg = data;
u_int16_t seg_size, as_size = 2;
u_int8_t seg_len, seg_type;
- int i, error = 0;
+ int error = 0;
if (len & 1)
/* odd length aspath are invalid */
@@ -436,6 +436,9 @@ aspath_verify(void *data, u_int16_t len, int as4byte)
as_size = 4;
for (; len > 0; len -= seg_size, seg += seg_size) {
+ const u_char *ptr;
+ int pos;
+
if (len < 2) /* header length check */
return (AS_ERR_BAD);
seg_type = seg[0];
@@ -461,9 +464,14 @@ aspath_verify(void *data, u_int16_t len, int as4byte)
/* empty aspath segments are not allowed */
return (AS_ERR_BAD);
- /* RFC 7607 - AS 0 is considered malformed */
- for (i = 0; i < seg_len; i++) {
- if (aspath_extract(seg, i) == 0)
+ /* RFC 7607 - AS 0 is considered malformed */
+ ptr = seg + 2;
+ for (pos = 0; pos < seg_len; pos++) {
+ u_int32_t as = 0;
+
+ ptr += as_size;
+ memcpy(&as, ptr, as_size);
+ if (as == 0)
return (AS_ERR_SOFT);
}
}