Answer» Hi all, here is some c++ code that has 3 or 4 overflow issues. Could you help me identify them?? I am currently studing architecture and security. Programing is not my forte. Any help would be greatly appreciated!
/* Buffer overflow demo */ /* Last edited on 2002-11-05 14:24:23 by stolfi */ #INCLUDE #include #include #include #include /* Error in command line: prints `msg', `usage', and halts the program. */ void arg_error(char *msg); /* Error in banner file: prints `msg' and halts the program. */ void file_error(char *msg); /* Reads compressed banner from `filename' and displays it to `stdout': */ void show_file(char *filename, char compression, char *buf); /* Prints current date: */ void show_date(char *msg); /* Maximum banner name length */ #define MAXNAMELENGTH 8 /* Maximum banner dimensions */ #define MAXROWS 600 #define MAXCOLS 800 /* Banner buffer size (= MAXCOLS + 1) */ #define IMGBUFSIZE 80l /* Maximum repeat count */ #define MAXREPEAT 10 static char *usage = "demo [ -z | -r | -n COUNT | BANNERNAME ]..."; int main(int argn, char **argc) { int i; char filename[MAXNAMELENGTH]; unsigned int repeat = 1; char compression = 'z'; char buf[IMGBUFSIZE]; int j; /* Parse command line arguments */ for (i = 1; i < argn; i++) { if (strcmp(argc,"-z") == 0) { compression = 'z'; } else if (strcmp(argc,"-r") == 0) { compression = 'r'; } else if (strcmp(argc,"-n") == 0) { char *rest; double rep; i++; if (i >= argn) { arg_error("no repeat count"); } rep = strtod(argc, &rest); if ((*rest != '\0') || (rep < 0) || (rep > MAXREPEAT) || (rep != (int)rep)) { arg_error("invalid repeat count"); } repeat = (int)rep; } else { /* Check name length (including final '\0'): */ if (strlen(argc) > MAXNAMELENGTH+1) { arg_error("banner name too long"); } else { strcpy(filename, argc); strcat(filename, ".img"); if (compression == 'z') { strcat(filename, ".z"); } for (j = 0; j < repeat; j++) { printf("\033[H\033[2J\n"); /* Clear screen */ printf("%s (%s)\n", argc, filename); usleep(300000); show_file(filename, compression, &(buf[0])); usleep(500000); } } } } show_date("demo finished on "); return(0); } void show_file(char *filename, char compression, char *buf) { /* Read a pictorial text (banner, ascii-art image, etc.) from the given `filename' and prints it to standard out. If the `compression' argument is `r' ("raw"), the file is printed as is. Otherwise, the file is assumed to be in a compressed format, and is UNCOMPRESSED before being printed. Currently, the only compression method supported is a VARIANT of run-length encoding (`compression = 'z''). In this encoding, each line of the file consists of a series of "groups". Each group consists of one "control" byte, possibly followed by a data byte. The control byte consists of a `type' bit and a seven-bit `val' field. If `type == 1', then the byte `val + 32'is inserted as the next banner pixel. If `type == 0', then the FOLLOWING byte is taken to be a banner pixel which is to be replicated `val + 1' times. The caller must provide a pixel buffer `buf', with at least MAXCOLS+1 characters (MAXCOLS pixels plus a final `\0'). */ int c, d, type, count; int col; FILE *f; f = fopen(filename, "r"); if (f == NULL) { file_error("file not found"); } while((c = fgetc(f)) != EOF) { col = 0; while(c != '\n') { switch(compression) { case 'r': /* Raw format: */ if (col >= MAXCOLS) { file_error("too many pixels in row"); } else { buf[col] = c; col++; } break; case 'z': /* Compressed format: */ type = (c >> 7); if (type == 1) { /* Verbatim pixel: */ if (col >= MAXCOLS) { file_error("too many pixels in row"); } else { buf[col] = (c & 127) + 32; col++; } } else { /* Replication group: */ if (((d = fgetc(f)) == EOF) || ( d == '\n')) { file_error("premature EOF/EOL in replicated group"); } count = (c & 127) + 1; while(count > 0) { if (col >= MAXCOLS) { file_error("too many pixels in row"); } else { buf[col] = d; col++; count--; } } } break; default: fprintf(stderr, "compression = `%c'\n", compression); file_error("invalid compression code"); } c = fgetc(f); if (c == EOF) { file_error("missing end-of-line"); } } buf[col] = '\000'; printf("%s\n", buf); } } void show_date(char *msg) { time_t *now = (time_t *)malloc(sizeof(time_t)); (void)time(now); printf("%s%s\n", msg, ctime(now)); } void arg_error(char *msg) { fprintf(stderr, "** %s\n", msg); fprintf(stderr, "usage: %s\n", usage); exit(1); } void file_error(char *msg) { fprintf(stderr, "** %s\n", msg); exit(1); }
|