Date: Sun, 1 May 2005 20:27:41 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 76333 for review Message-ID: <200505012027.j41KRfx8069465@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505012027.j41KRfx8069465>