From owner-p4-projects@FreeBSD.ORG Sun May 1 20:27:42 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D576016A4D0; Sun, 1 May 2005 20:27:41 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9486816A4CE for ; Sun, 1 May 2005 20:27:41 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6A38443D39 for ; Sun, 1 May 2005 20:27:41 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j41KRfsA069468 for ; Sun, 1 May 2005 20:27:41 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j41KRfx8069465 for perforce@freebsd.org; Sun, 1 May 2005 20:27:41 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sun, 1 May 2005 20:27:41 GMT Message-Id: <200505012027.j41KRfx8069465@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Subject: PERFORCE change 76333 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 May 2005 20:27:42 -0000 http://perforce.freebsd.org/chv.cgi?CH=76333 Change 76333 by rwatson@rwatson_paprika on 2005/05/01 20:26:59 Teach au_read_rec() to recognize file tokens and treat them as a "complete record" from the perspective of the caller. All other audit tokens occur only in the context of a record, so matching the record header is the right approach for them, just not the file token. Affected files ... .. //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#9 edit Differences ... ==== //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#9 (text+ko) ==== @@ -2243,6 +2243,13 @@ * Rread a record from the file pointer, store data in buf * memory for buf is also allocated in this function * and has to be free'd outside this call + * + * au_read_rec() handles two possibilities: a stand-alone file token, or a + * complete audit record. + * + * XXXRW: Note that if we hit an error, we leave the stream in an unusable + * state, because it will be partly offset into a record. We should rewind + * or do something more intelligent. */ int au_read_rec(FILE *fp, u_char **buf) { @@ -2251,44 +2258,97 @@ u_int32_t bytestoread; u_char type; + u_int32_t sec, msec; + u_int16_t filenamelen; + type = fgetc(fp); - /* record must begin with a header token */ - if(type != AU_HEADER_32_TOKEN) { - errno = EINVAL; - return -1; - } + + switch (type) { + case AU_HEADER_32_TOKEN: + case AU_HEADER_EX_32_TOKEN: + case AU_HEADER_64_TOKEN: + case AU_HEADER_EX_64_TOKEN: + /* read the record size from the token */ + if (fread(&recsize, 1, sizeof(u_int32_t), fp) < + sizeof(u_int32_t)) { + errno = EINVAL; + return -1; + } + recsize = be32toh(recsize); + + /* Check for recsize sanity */ + if (recsize < (sizeof(u_int32_t) + sizeof(u_char))) { + errno = EINVAL; + return -1; + } + + *buf = (u_char *)malloc(recsize * sizeof(u_char)); + if (*buf == NULL) + return -1; + bptr = *buf; + memset(bptr, 0, recsize); + + /* store the token contents already read, back to the buffer*/ + *bptr = type; + bptr++; + be32enc(bptr, recsize); + bptr += sizeof(u_int32_t); - /* read the record size from the token */ - if(fread(&recsize, 1, sizeof(u_int32_t), fp) < sizeof(u_int32_t)) { - errno = EINVAL; - return -1; - } - recsize = be32toh(recsize); + /* now read remaining record bytes */ + bytestoread = recsize - sizeof(u_int32_t) - sizeof(u_char); - /* Check for recsize sanity */ - if(recsize < (sizeof(u_int32_t) + sizeof(u_char))) { - errno = EINVAL; - return -1; - } + if (fread(bptr, 1, bytestoread, fp) < bytestoread) { + free(*buf); + errno = EINVAL; + return -1; + } + break; - *buf = (u_char *)malloc(recsize * sizeof(u_char)); - if(*buf == NULL) { - return -1; - } - bptr = *buf; - memset(bptr, 0, recsize); + case AU_FILE_TOKEN: + /* + * The file token is variable-length, as it includes a + * pathname. As a result, we have to read incrementally + * until we know the total length, then allocate space and + * read the rest. + */ + if (fread(&sec, 1, sizeof(sec), fp) < sizeof(sec)) { + errno = EINVAL; + return -1; + } + if (fread(&msec, 1, sizeof(msec), fp) < sizeof(msec)) { + errno = EINVAL; + return -1; + } + if (fread(&filenamelen, 1, sizeof(filenamelen), fp) < + sizeof(filenamelen)) { + errno = EINVAL; + return -1; + } + recsize = sizeof(type) + sizeof(sec) + sizeof(msec) + + sizeof(filenamelen) + ntohs(filenamelen); + *buf = malloc(recsize); + if (*buf == NULL) + return -1; + bptr = *buf; - /* store the token contents already read, back to the buffer*/ - *bptr = type; - bptr++; - be32enc(bptr, recsize); - bptr += sizeof(u_int32_t); + bcopy(&type, bptr, sizeof(type)); + bptr += sizeof(type); + bcopy(&sec, bptr, sizeof(sec)); + bptr += sizeof(sec); + bcopy(&msec, bptr, sizeof(msec)); + bptr += sizeof(msec); + bcopy(&filenamelen, bptr, sizeof(filenamelen)); + bptr += sizeof(filenamelen); - /* now read remaining record bytes */ - bytestoread = recsize - sizeof(u_int32_t) - sizeof(u_char); + if (fread(bptr, 1, ntohs(filenamelen), fp) < + ntohs(filenamelen)) { + free(buf); + errno = EINVAL; + return -1; + } - if(fread(bptr, 1, bytestoread, fp) < bytestoread) { - free(*buf); + break; + default: errno = EINVAL; return -1; }