//------------------------------------------------------------------- // visual.c // // This module constitutes a simple 'scientific visualization' // exercise: it creates a '/proc' pseudo-file which lets users // display an image for the 'task_union' object, showing sizes // and relative locations for the process-descriptor and stack // regions, and an indication of the 'garbage' area separating // these data-structures. It was prompted by a question about // the possibility, and liklihood, that the kernel stack might // expand downward far enough to overwrite some portion of the // process descriptor, thereby corrupting and perhaps crashing // the operating system. // // programmer: ALLAN CRUSE // written on: 12 FEB 2003 //------------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include // for create_proc_read_entry() #define SUCCESS 0 #define GRANULARITY 8 #define CELLS ( sizeof( union task_union)/GRANULARITY ) static char modname[] = "visual"; static unsigned char glyph[ CELLS ]; static int my_proc_read( char *buf, char **start, off_t off, int count, int *eof, void *data ); int init_module( void ) { printk( "<1>\nInstalling \'%s\' module\n", modname ); create_proc_read_entry( modname, 0, NULL, my_proc_read, NULL ); return SUCCESS; } void cleanup_module( void ) { remove_proc_entry( modname, NULL ); printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE("GPL"); static int my_proc_read( char *buf, char **start, off_t off, int count, int *eof, void *data ) { unsigned char *cp = (unsigned char *)current; int d_top = sizeof( struct task_struct )/GRANULARITY; int s_top, i, j, len; unsigned long tos; // use inline assembly-language to get esp-value asm(" movl %%esp, %0 " : "=m" (tos) ); s_top = (tos & 0x00001FFF)/GRANULARITY; // assign character-glyphs indicating zero or nonzero for (i = 0; i < CELLS; i++) { int k = GRANULARITY*i; unsigned char total = 0; for (j = 0; j < GRANULARITY; j++) total |= cp[ k + j ]; glyph[ i ] = ( total ) ? '+' : '-'; } // assign character-glyphs for descriptor and stack regions for (i = 0; i < CELLS; i++) { if ( i < d_top ) glyph[i] = 'D'; if ( i >= s_top ) glyph[i] = 'S'; } // display title, assigned character-glyphs, and the legend len = 0; len += sprintf( buf+len, "\n\n\n A scientific visualization " ); len += sprintf( buf+len, "of the Linux \'task_union\' object " ); len += sprintf( buf+len, "(pid=%d)\n", current->pid ); for (i = 0; i < CELLS; i++) { int u = CELLS - (i+1); int k = GRANULARITY*u; if ( ( i % 64 ) == 0 ) len += sprintf( buf+len, "\n " ); len += sprintf( buf+len, "%c", glyph[u] ); if ( ( i % 64 ) == 63 ) len += sprintf( buf+len, " %04X", cp+k ); } len += sprintf( buf+len, "\n\n\n" ); len += sprintf( buf+len, "\tLegend: " ); len += sprintf( buf+len, " \'S\'=stack " ); len += sprintf( buf+len, " \'D\'=descriptor " ); len += sprintf( buf+len, " \'-\'=zero " ); len += sprintf( buf+len, " \'+\'=nonzero " ); len += sprintf( buf+len, "\n\n\n" ); *eof = 1; return len; }