/** * bio_integrity_process - Process integrity metadata for a bio * @bio: bio to generate/verify integrity metadata for * @proc_fn: Pointer to the relevant processing function */ static int bio_integrity_process(struct bio *bio, integrity_processing_fn *proc_fn) { struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); struct blk_integrity_iter iter; struct bvec_iter bviter; struct bio_vec bv; struct bio_integrity_payload *bip = bio_integrity(bio); unsigned int ret = 0; void *prot_buf = page_address(bip->bip_vec->bv_page) + bip->bip_vec->bv_offset; iter.disk_name = bio->bi_bdev->bd_disk->disk_name; iter.interval = bi->interval; iter.seed = bip_get_seed(bip); iter.prot_buf = prot_buf; bio_for_each_segment(bv, bio, bviter) { void *kaddr = kmap_atomic(bv.bv_page); iter.data_buf = kaddr + bv.bv_offset; iter.data_size = bv.bv_len; ret = proc_fn(&iter); if (ret) { kunmap_atomic(kaddr); return ret; } kunmap_atomic(kaddr); }
static void IncIterateMods( mod_entry *mod, void (*proc_fn)(mod_entry *), bool dochanged ) /***********************************************************************/ { bool haschanged; for( ; mod != NULL; mod = mod->n.next_mod ) { haschanged = mod->modinfo & MOD_KILL || mod->f.source->status & STAT_HAS_CHANGED; if( haschanged == dochanged ) { proc_fn( mod ); } } }
/* Iterate through processes in the system. */ void iterate_processes(char **limit, void (*proc_fn)(int, void *), void *data) { /* Open /proc */ DIR *proc_dir = opendir("/proc"); if (proc_dir == NULL) { fprintf(stderr, "Could not open /proc."); exit(1); } /* Read through processes. */ while (1) { /* Read directory. */ struct dirent *e = readdir(proc_dir); if (e == NULL) break; /* Skip non-directories. */ if ((e->d_type & DT_DIR) == 0) continue; /* Process? */ int p = atoi(e->d_name); if (p == 0) continue; if (limit != NULL) { int skip = 1; /* Find the name of the process we're looking at. */ char name[PATH_MAX]; if (name_of(p, name, PATH_MAX) != 0) /* This process doesn't have a name. Poor thing. */ continue; /* Determine if this process matches any of the processes we should * be considering. */ char **l; for (l = limit; *l != NULL; l++) { if (!strcmp(name, *l)) { skip = 0; break; } char *last_slash = strrchr(name, '/'); if (last_slash != NULL && !strcmp(last_slash + 1, *l)) { skip = 0; break; } } if (skip == 1) /* No match. */ continue; #if DEBUG printf("Considering %s...\n", name); #endif } proc_fn(p, data); } /* Cleanup. */ closedir(proc_dir); }
static void pmaps(int pid, print_flags_t pflags, regex_t *regex, int fd_kflags, int fd_kcount) { FILE *maps = NULL; int fd_p=-1; unsigned long start_addr, end_addr; char *line=0; size_t line_n=0; maps = fopen(proc_fn(pid, "maps"), "r"); if (!maps) { fprintf(stderr, "ERROR: could not open /proc/%d/maps: %s\n", pid, strerror(errno)); goto done; } fd_p = open(proc_fn(pid, "pagemap"), O_RDONLY); if (fd_p<0) { fprintf(stderr, "ERROR: could not open /proc/%d/pagemap: %s\n", pid, strerror(errno)); goto done; } while (1) { int ret = getline(&line, &line_n, maps); if (ret == -1) { goto done; } if (pflags & STACK_ONLY) { if (strstr(line, "[stack]") == NULL) continue; } else if (pflags & HEAP_ONLY) { if (strstr(line, "[heap]") == NULL) continue; } else if (regex) { if (regexec(regex, line, 0, NULL, 0) != 0) continue; } if (sscanf(line, "%lx-%lx", &start_addr, &end_addr) != 2) { (void) fprintf(stderr, "ERROR: did not understand line from /proc/pid/maps. :(\n"); goto done; } (void) printf("%s", line); unsigned long page_start = start_addr / pagesize; unsigned long page_end = end_addr / pagesize; x_lseek(fd_p, sizeof(uint64_t)*page_start, SEEK_SET); unsigned long nr_read = 0; unsigned long nr_read_total = 0; for (; page_start < page_end; page_start += BSIZE, nr_read_total += nr_read) { nr_read = min_ul(page_end-page_start, BSIZE); if (read(fd_p, pagemap, nr_read*sizeof(uint64_t)) != (ssize_t)(nr_read*sizeof(uint64_t))) { // Reading the /proc/pid/pagemap entry for // /proc/pid/maps [vsyscall] resulted in zero // byte reads. Let's just ignore such cases. continue; } populate(fd_kflags, pageflags, nr_read); populate(fd_kcount, pagecount, nr_read); for (unsigned i=0; i < nr_read; ++i) { if (PMAP_PRESENT&pagemap[i] && !(pflags & SWAPPED_ONLY)) { printf(" %#lx -> pfn:%#08llx count:%4llu flags:%s\n", start_addr + (nr_read_total+i)*pagesize, PMAP_PFN&pagemap[i], (unsigned long long)pagecount[i], flags2str(pageflags[i])); } else if (PMAP_SWAPPED&pagemap[i] && !(pflags & RESIDENT_ONLY)) { printf(" #%#lx -> swaptype:%#llx swapoff:%#08llx\n", start_addr + (nr_read_total+i)*pagesize, PMAP_SWAP_TYPE&pagemap[i], (PMAP_SWAP_OFF&pagemap[i])>>5); } else if (!(pflags & (SWAPPED_ONLY|RESIDENT_ONLY))) { printf(" !%#lx\n", start_addr + (nr_read_total+i)*pagesize); } } }