From 24f1cc20d7fedcd49bb7d8d267527799f7414435 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Wed, 15 May 2019 18:19:05 +0200 Subject: [PATCH] fix memory corruption in rewrite-vendor --- hash.c | 1 - hash.h | 1 + rewrite.c | 32 +++++++++++++++++++------------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hash.c b/hash.c index 19d6c18..051c7e1 100644 --- a/hash.c +++ b/hash.c @@ -3,7 +3,6 @@ #include #include -#include #include "list.h" #include "hash.h" diff --git a/hash.h b/hash.h index d22a88c..ccb2917 100644 --- a/hash.h +++ b/hash.h @@ -4,6 +4,7 @@ #ifndef SYS_SOLARIS9 #include #endif +#include struct hash { struct list *hashlist; diff --git a/rewrite.c b/rewrite.c index 32a84ad..b383103 100644 --- a/rewrite.c +++ b/rewrite.c @@ -456,27 +456,33 @@ int replacesubtlv(struct tlv *vendortlv, uint8_t *p, struct tlv *newtlv) { } int dorewritemodvattr(struct tlv *vendortlv, struct modattr *modvattr) { - uint8_t *p; struct tlv *tmpattr; + int offset; if (vendortlv->l <= 4 || !attrvalidate(vendortlv->v+4, vendortlv->l-4)) return 0; - for (p = vendortlv->v+4; p < (vendortlv->v + vendortlv->l); p = p+ATTRLEN(p)) { - if (ATTRTYPE(p) == modvattr->t) { - tmpattr = maketlv(ATTRTYPE(p), ATTRVALLEN(p), ATTRVAL(p)); + for (offset = 4; offset < vendortlv->l; offset += ATTRLEN(vendortlv->v+offset)) { + if (ATTRTYPE(vendortlv->v+offset) == modvattr->t) { + tmpattr = maketlv(ATTRTYPE(vendortlv->v+offset), ATTRVALLEN(vendortlv->v+offset), ATTRVAL(vendortlv->v+offset)); if (dorewritemodattr(tmpattr, modvattr)) { - int size_diff = tmpattr->l - ATTRVALLEN(p); - uint8_t *next_attr = p+ATTRLEN(p); - uint8_t rem_size = (vendortlv->v + vendortlv->l) - next_attr; + int size_diff = tmpattr->l - ATTRVALLEN(vendortlv->v+offset); + int rem_size = vendortlv->l - offset - ATTRLEN(vendortlv->v+offset); + uint8_t *next; - if (size_diff < 0) - memmove(next_attr + size_diff, next_attr, rem_size); - if (!resizeattr(vendortlv, vendortlv->l+size_diff)) - return 0; if (size_diff > 0) - memmove(next_attr + size_diff, next_attr, rem_size); + if (!resizeattr(vendortlv, vendortlv->l+size_diff)) { + freetlv(tmpattr); + return 0; + } + next = vendortlv->v + offset + ATTRLEN(vendortlv->v+offset); + memmove(next + size_diff, next, rem_size); + if (size_diff < 0) + if (!resizeattr(vendortlv, vendortlv->l+size_diff)) { + freetlv(tmpattr); + return 0; + } - tlv2buf(p, tmpattr); + tlv2buf(vendortlv->v+offset, tmpattr); } else { freetlv(tmpattr); return 0;