From owner-freebsd-bugs Tue Oct 22 4:15:53 2002 Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9929A37B401 for ; Tue, 22 Oct 2002 04:15:48 -0700 (PDT) Received: from mallaury.noc.nerim.net (mallaury.noc.nerim.net [62.4.17.82]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9BE5843E4A for ; Tue, 22 Oct 2002 04:15:47 -0700 (PDT) (envelope-from meadele@nerim.net) Received: from nerim.net (bzero.net [80.65.224.39]) by mallaury.noc.nerim.net (Postfix) with ESMTP id 9C2B662E8B for ; Tue, 22 Oct 2002 13:15:39 +0200 (CEST) Message-ID: <3DB55EB9.5000900@nerim.net> Date: Tue, 22 Oct 2002 14:20:41 +0000 From: mm User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:0.9.9) Gecko/20020312 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-bugs@freebsd.org Subject: libutil: property.c bug (properties_read) Content-Type: multipart/mixed; boundary="------------040306070003060106090801" Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org This is a multi-part message in MIME format. --------------040306070003060106090801 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hi, There is a bad boundary check in properties_read() in libutil when parsing 'name=value'. I patched property.c and added some corrections: - corrected bad boundary check. - ignore characters after space unless value is enclosed with brackets. - ignore characters after terminating bracket. - check for malloc/strdup return value. The attached path applies on /usr/src/lib/libutil/property.c shipped with FreeBSD 4.7-STABLE. --------------040306070003060106090801 Content-Type: text/plain; name="property.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="property.c.patch" --- property.c Mon Oct 21 18:50:44 2002 +++ property.c Tue Oct 22 13:45:20 2002 @@ -47,9 +47,23 @@ properties n; n = (properties)malloc(sizeof(struct _property)); + if (n == NULL) + return NULL; n->next = NULL; - n->name = name ? strdup(name) : NULL; - n->value = value ? strdup(value) : NULL; + if (name) { + n->name = strdup(name); + if (n->name == NULL) + return NULL; + } + else + n->name = NULL; + if (value) { + n->value = strdup(value); + if (n->value == NULL) + return NULL; + } + else + n->value = NULL; return n; } @@ -62,7 +76,7 @@ char buf[BUFSIZ * 4]; int bp, n, v, max; enum { LOOK, COMMENT, NAME, VALUE, MVALUE, COMMIT, FILL, STOP } state; - int ch = 0, blevel = 0; + int ch = 0, blevel = 0, ign = 0; n = v = bp = max = 0; head = ptr = NULL; @@ -91,38 +105,28 @@ if (isspace(ch)) continue; /* Allow shell or lisp style comments */ - else if (ch == '#' || ch == ';') { + else if (ch == '#' || ch == ';' || + (!isalnum(ch) && ch != '_')) { state = COMMENT; continue; } - else if (isalnum(ch) || ch == '_') { - if (n >= PROPERTY_MAX_NAME) { - n = 0; - state = COMMENT; - } - else { - hold_n[n++] = ch; - state = NAME; - } - } - else - state = COMMENT; /* Ignore the rest of the line */ - break; - - case COMMENT: - if (ch == '\n') - state = LOOK; - break; + state = NAME; + /* fall through */ case NAME: - if (ch == '\n' || !ch) { + if (ch == '\n') { hold_n[n] = '\0'; hold_v[0] = '\0'; v = n = 0; state = COMMIT; } - else if (isspace(ch)) - continue; + else if (n == PROPERTY_MAX_NAME) { + warnx("properties_read: name exceeds max length"); + state = COMMENT; + n = v = 0; + } + else if (isspace(ch)) + continue; else if (ch == '=') { hold_n[n] = '\0'; v = n = 0; @@ -133,44 +137,45 @@ break; case VALUE: - if (v == 0 && ch == '\n') { + if (ch == '\n') { hold_v[v] = '\0'; - v = n = 0; + ign = v = n = 0; state = COMMIT; } - else if (v == 0 && isspace(ch)) - continue; - else if (ch == '{') { - state = MVALUE; - ++blevel; + else if (isspace(ch) || ign) { + if (v != 0) + ign = 1; /* skip trailing characters */ + continue; } - else if (ch == '\n' || !ch) { - hold_v[v] = '\0'; + else if (v == PROPERTY_MAX_VALUE) { + warnx("properties_read: value exceeds max length"); + state = COMMENT; v = n = 0; - state = COMMIT; } - else { - if (v >= PROPERTY_MAX_VALUE) { - state = COMMENT; - v = n = 0; - break; - } - else - hold_v[v++] = ch; + else if (v == 0 && ch == '{') { + state = MVALUE; + ++blevel; } + else + hold_v[v++] = ch; break; case MVALUE: /* multiline value */ - if (v >= PROPERTY_MAX_VALUE) { - warn("properties_read: value exceeds max length"); - state = COMMENT; - n = v = 0; - } + if (blevel == 0) { /* skip trailing characters */ + if (ch == '\n') + state = COMMIT; + else + continue; + } else if (ch == '}' && !--blevel) { hold_v[v] = '\0'; - v = n = 0; - state = COMMIT; + blevel = v = n = 0; + } + else if (v == PROPERTY_MAX_VALUE) { + warnx("properties_read: value exceeds max length"); + state = COMMENT; + blevel = n = v = 0; } else { hold_v[v++] = ch; @@ -180,14 +185,26 @@ break; case COMMIT: - if (!head) + if (!head) { head = ptr = property_alloc(hold_n, hold_v); + if (head == NULL) + return NULL; + } else { ptr->next = property_alloc(hold_n, hold_v); - ptr = ptr->next; + if (ptr->next == NULL) { + properties_free(head); + return NULL; + } + ptr = ptr->next; } state = LOOK; v = n = 0; + break; + + case COMMENT: + if (ch == '\n') + state = LOOK; break; case STOP: --------------040306070003060106090801-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message