int main(int argc, char **argv) { srand(time(NULL)); if (argc>1 && strcmp(argv[1], "intercept") == 0) return do_intercept(atoi(argv[2]), atoi(argv[3])); if (argc>1 && strcmp(argv[1], "release") == 0) return do_release(atoi(argv[2]), atoi(argv[3])); if (argc>1 && strcmp(argv[1], "nonroot") == 0) return do_nonroot(atoi(argv[2])); test("insmod interceptor.ko %s", "", system("insmod interceptor.ko") == 0); test("bad MY_CUSTOM_SYSCALL args%s", "", vsyscall_arg(MY_CUSTOM_SYSCALL, 3, 100, 0, 0) == -EINVAL); do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_intercept(__NR_exit, 0); do_release(__NR_exit, 0); test_syscall(SYS_open); /* The above line of code tests SYS_open. * Feel free to add more tests here for other system calls, * once you get everything to work; check Linux documentation * for other syscall number definitions. */ test("rmmod interceptor.ko %s", "", system("rmmod interceptor") == 0); return 0; }
int op_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { __u64 pos; errcode_t rc; unsigned int bytes; ext2_file_t efile = EXT2FS_FILE(fi->fh); ext2_filsys e2fs = current_ext2fs(); debugf("enter"); debugf("path = %s", path); efile = do_open(e2fs, path, O_RDONLY); rc = ext2fs_file_llseek(efile, offset, SEEK_SET, &pos); if (rc) { do_release(efile); return -EINVAL; } rc = ext2fs_file_read(efile, buf, size, &bytes); if (rc) { do_release(efile); return -EIO; } do_release(efile); debugf("leave"); return bytes; }
int main(int argc, char **argv) { srand(time(NULL)); if (argc > 1 && strcmp(argv[1], "intercept") == 0) return do_intercept(atoi(argv[2]), atoi(argv[3])); if (argc > 1 && strcmp(argv[1], "release") == 0) return do_release(atoi(argv[2]), atoi(argv[3])); if (argc > 1 && strcmp(argv[1], "start") == 0) return do_start(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); if (argc > 1 && strcmp(argv[1], "stop") == 0) return do_stop(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); if (argc > 1 && strcmp(argv[1], "monitor") == 0) return test_monitor(atoi(argv[2]), TRUE); if (argc > 1 && strcmp(argv[1], "nonroot") == 0) return do_nonroot(atoi(argv[2])); struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = on_quit; if (sigaction(SIGQUIT, &sa, NULL) == -1) perror("Cannot register signal handler"); test("insmod interceptor.ko %s", "", system("insmod interceptor.ko") == 0); test("bad MY_SYSCALL args%s", "", vsyscall_arg(MY_CUSTOM_SYSCALL, 3, 100, 0, 0) == -EINVAL); do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_intercept(__NR_exit, 0); do_release(__NR_exit, 0); test_syscall(SYS_open); /* The above line of code tests SYS_open. Feel free to add more tests here for other system calls, once you get everything to work; check Linux documentation for other syscall number definitions. */ do_intercept(SYS_open, 0); do_start(SYS_open, -1, 0); test_monitor(SYS_open, TRUE); test("rmmod interceptor.ko %s", "", system("rmmod interceptor") == 0); test_monitor(SYS_open, FALSE); return 0; }
void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_as_guest("./test_full nonroot %d", syscall, 0); do_start(syscall, -2, -EINVAL); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_start(syscall, 1, 0); do_as_guest("./test_full stop %d 1 %d", syscall, -EPERM); do_stop(syscall, 1, 0); do_as_guest("./test_full start %d -1 %d", syscall, 0); do_stop(syscall, last_child, -EINVAL); do_release(syscall, 0); puts("----- START OF test_PASS -----"); test_PASS(syscall); puts("----- END OF test_PASS -----"); puts("----- START OF test_A -----"); test_A(syscall); puts("----- END OF test_A -----"); puts("----- START OF test_B -----"); test_B(syscall, TRUE); puts("----- END OF test_B -----"); puts("----- START OF test_CDE ----"); test_CDE(syscall); puts("----- END OF test_CDE ----"); }
static int configfs_release_bin_file(struct inode *inode, struct file *filp) { struct configfs_buffer *buffer = filp->private_data; struct dentry *dentry = filp->f_path.dentry; struct config_item *item = to_item(dentry->d_parent); struct configfs_item_operations *ops = buffer->ops; struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); ssize_t len = 0; int ret; buffer->read_in_progress = 0; if (buffer->write_in_progress) { buffer->write_in_progress = 0; len = ops->write_bin_attribute(item, bin_attr, buffer->bin_buffer, buffer->bin_buffer_size); /* vfree on NULL is safe */ vfree(buffer->bin_buffer); buffer->bin_buffer = NULL; buffer->bin_buffer_size = 0; buffer->needs_read_fill = 1; } ret = do_release(inode, filp, to_item(filp->f_path.dentry->d_parent), to_attr(filp->f_path.dentry), CONFIGFS_ITEM_BIN_ATTR); if (len < 0) return len; return ret; }
void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_intercept(syscall, -EBUSY); do_as_guest("./test_intercept nonroot %d", syscall, 0); do_release(syscall, 0); }
static void mutex_destroy( struct object *obj ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); if (!mutex->count) return; mutex->count = 0; do_release( mutex ); }
void test_A(int syscall) { // test negative syscall number do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_start(-1, -1, -EINVAL); do_stop(-1, -1, -EINVAL); // test the last syscall do_intercept(MAX_SYSCALLS - 1, 0); do_start(MAX_SYSCALLS - 1, -1, 0); do_stop(MAX_SYSCALLS - 1, -1, 0); do_release(MAX_SYSCALLS - 1, 0); // test greater than NR_syscalls do_intercept(MAX_SYSCALLS, -EINVAL); do_release(MAX_SYSCALLS, -EINVAL); do_start(MAX_SYSCALLS, -1, -EINVAL); do_stop(MAX_SYSCALLS, -1, -EINVAL); do_intercept(MAX_SYSCALLS + 1, -EINVAL); do_release(MAX_SYSCALLS + 1, -EINVAL); do_start(MAX_SYSCALLS + 1, -1, -EINVAL); do_stop(MAX_SYSCALLS + 1, -1, -EINVAL); // test MY_CUSTOM_SYSCALL do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_start(MY_CUSTOM_SYSCALL, -1, -EINVAL); do_stop(MY_CUSTOM_SYSCALL, -1, -EINVAL); // test on pids do_intercept(syscall, 0); do_start(syscall, -2, -EINVAL); do_stop(syscall, -2, -EINVAL); do_release(syscall, 0); }
void abandon_mutexes( struct thread *thread ) { struct list *ptr; while ((ptr = list_head( &thread->mutex_list )) != NULL) { struct mutex *mutex = LIST_ENTRY( ptr, struct mutex, entry ); assert( mutex->owner == thread ); mutex->count = 0; mutex->abandoned = 1; do_release( mutex ); } }
int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); do_start(syscall, 0, -EPERM); do_stop(syscall, 0, -EPERM); do_start(syscall, 1, -EPERM); do_stop(syscall, 1, -EPERM); do_start(syscall, getpid(), 0); do_start(syscall, getpid(), -EBUSY); do_monitor(syscall); do_stop(syscall, getpid(), 0); do_stop(syscall, getpid(), -EINVAL); return 0; }
int op_truncate(const char *path, off_t length) { int rt; ext2_file_t efile; ext2_filsys e2fs = current_ext2fs(); debugf("enter"); debugf("path = %s", path); rt = do_check(path); if (rt != 0) { debugf("do_check(%s); failed", path); return rt; } efile = do_open(e2fs, path, O_WRONLY); if (efile == NULL) { debugf("do_open(%s); failed", path); return -ENOENT; } rt = ext2fs_file_set_size(efile, length); if (rt) { do_release(efile); debugf("ext2fs_file_set_size(efile, %d); failed", length); return rt; } rt = do_release(efile); if (rt != 0) { debugf("do_release(efile); failed"); return rt; } debugf("leave"); return 0; }
int op_write (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { size_t rt; ext2_file_t efile = EXT2FS_FILE(fi->fh); ext2_filsys e2fs = current_ext2fs(); debugf("enter"); debugf("path = %s", path); efile = do_open(e2fs, path, O_WRONLY); rt = do_write(efile, buf, size, offset); do_release(efile); debugf("leave"); return rt; }
bool Rotateable::on_release(GdkEventButton *event) { if (dragging && working) { double angle = atan2(event->y - drag_started_y, event->x - drag_started_x); double force = CLAMP(-(angle - current_axis) / maxdecl, -1, 1); if (fabs(force) < 0.002) force = 0; // snap to zero do_release(force, modifier); current_axis = axis; dragging = false; working = false; return true; } dragging = false; working = false; return false; }
void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_intercept(syscall, -EBUSY); do_as_guest("./test_full nonroot %d", syscall, 0); do_start(syscall, -2, -EINVAL); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_start(syscall, 1, 0); do_as_guest("./test_full stop %d 1 %d", syscall, -EPERM); do_stop(syscall, 1, 0); do_as_guest("./test_full start %d -1 %d", syscall, 0); do_stop(syscall, last_child, -EINVAL); do_release(syscall, 0); }
int op_release (const char *path, struct fuse_file_info *fi) { int rt; ext2_file_t efile = (void *) (unsigned long) fi->fh; debugf("enter"); debugf("path = %s (%p)", path, efile); rt = do_release(efile); if (rt != 0) { debugf("do_release() failed"); return rt; } debugf("leave"); return 0; }
static int mutex_signal( struct object *obj, unsigned int access ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); if (!(access & SYNCHRONIZE)) { set_error( STATUS_ACCESS_DENIED ); return 0; } if (!mutex->count || (mutex->owner != current)) { set_error( STATUS_MUTANT_NOT_OWNED ); return 0; } if (!--mutex->count) do_release( mutex ); return 1; }
void start_release() { if( !release_started_ ) { #ifdef VTRACE_FULL VT_TRACER("incoherent start_release"); #endif DVLOG(5) << "Worker " << Grappa::current_worker() << " issuing release for " << *request_address_ << " * " << *count_ ; release_started_ = true; size_t total_bytes = *count_ * sizeof(T); // allocate enough requests/messages that we don't run out size_t nmsg = total_bytes / block_size + 2; size_t msg_size = sizeof(Grappa::PayloadMessage<RequestArgs>); do_release(); } }
void test_B(int syscall, int iamroot) { #define subtestroot(s) printf((s" as %s\n"), (iamroot)?"root":"nonroot") subtestroot("EPERM: intercept"); do_intercept(syscall, iamroot ? 0 : -EPERM); subtestroot("EPERM: monitor self"); do_start(syscall, -1, 0); do_stop(syscall, -1, 0); subtestroot("EPERM: monitor all processes"); do_start(syscall, 0, iamroot ? 0 : -EPERM); do_stop(syscall, 0, iamroot ? 0 : -EPERM); subtestroot("EPERM: monitor init process"); do_start(syscall, 1, iamroot ? 0 : -EPERM); do_stop(syscall, 1, iamroot ? 0 : -EPERM); subtestroot("EPERM: release"); do_release(syscall, iamroot ? 0 : -EPERM); #undef subtestroot }
/* note this test is run after all processes have been intercepted*/ int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); do_start(syscall, 0, -EPERM); do_stop(syscall, 0, -EPERM); do_start(syscall, 1, -EPERM); do_stop(syscall, 1, -EPERM); do_start(syscall, getpid(), 0); do_start(syscall, getpid(), -EBUSY); test_monitor(syscall, TRUE); do_stop(syscall, getpid(), 0); do_stop(syscall, getpid(), -EINVAL); puts("----- START OF test_B -----"); test_B(syscall, FALSE); puts("----- END OF test_B -----"); return 0; }
bool Rotateable::on_motion(GdkEventMotion *event) { if (dragging) { double dist = Geom::L2(Geom::Point(event->x, event->y) - Geom::Point(drag_started_x, drag_started_y)); double angle = atan2(event->y - drag_started_y, event->x - drag_started_x); if (dist > 20) { working = true; double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1); if (fabs(force) < 0.002) force = 0; // snap to zero if (modifier != get_single_modifier(modifier, event->state)) { // user has switched modifiers in mid drag, close past drag and start a new // one, redefining axis temporarily do_release(force, modifier); current_axis = angle; modifier = get_single_modifier(modifier, event->state); } else { do_motion(force, modifier); } } Inkscape::UI::Tools::gobble_motion_events(GDK_BUTTON1_MASK); return true; } return false; }
int restore_line(const char *filename,uint64_t lv,char *line) { char *ptr; uint32_t ts; int status; char* errormsgs[]={ ERROR_STRINGS }; status = ERROR_MISMATCH; ptr = line; EAT(ptr,filename,lv,':'); EAT(ptr,filename,lv,' '); GETU32(ts,ptr); EAT(ptr,filename,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(filename,lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ACQUIRE",7)==0) { status = do_acquire(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_acquire(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(filename,lv,ts,ptr+8); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(filename,lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(filename,lv,ts,ptr+13); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'Q': if (strncmp(ptr,"QUOTA",5)==0) { status = do_quota(filename,lv,ts,ptr+5); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(filename,lv,ts,ptr+12); } else if (strncmp(ptr,"SETXATTR",8)==0) { status = do_setxattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(filename,lv,ts,ptr+7); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(filename,lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; default: printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } if (status>STATUS_OK) { printf("%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]); } return status; }
static int configfs_release_file(struct inode *inode, struct file *filp) { return do_release(inode, filp, to_item(filp->f_path.dentry->d_parent), to_attr(filp->f_path.dentry), CONFIGFS_ITEM_ATTR); }
int restore(void) { FILE *fd; char buff[10000]; char *ptr; uint64_t v,lv; uint32_t ts; uint8_t status; uint32_t dplen; char *datapath = NULL; char *logpath = NULL; char* errormsgs[]={ ERROR_STRINGS }; v = shadow_fs_getversion(); lv = 0; MFSLOG(LOG_NOTICE,"meta data version: %"PRIu64"",v); datapath = strdup(DATA_PATH); dplen = strlen(datapath); logpath = malloc(dplen+sizeof("/changelog.0.mfs")); memcpy(logpath,datapath,dplen); memcpy(logpath+dplen,"/changelog.0.mfs",sizeof("/changelog.0.mfs")); fd = fopen(logpath,"r"); if (fd==NULL) { MFSLOG(LOG_NOTICE,"can't open changemeta file: %s",logpath); return 1; } while (fgets(buff,10000,fd)) { ptr = buff; GETU64(lv,ptr); if (lv<v) { // skip } else { status = ERROR_MISMATCH; EAT(ptr,lv,':'); EAT(ptr,lv,' '); GETU32(ts,ptr); EAT(ptr,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(lv,ts,ptr+6); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_aquire(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(lv,ts,ptr+8); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(lv,ts,ptr+13); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(lv,ts,ptr+10); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(lv,ts,ptr+10); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(lv,ts,ptr+4); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(lv,ts,ptr+4); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(lv,ts,ptr+12); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(lv,ts,ptr+7); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; default: MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } /** * let the restore continue if we missed some meta data, otherwise the * * Dongyang Zhang */ if (status!=STATUS_OK) { MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]); return 1; } v = shadow_fs_getversion(); if (lv+1!=v) { MFSLOG(LOG_ERR,"%"PRIu64": version mismatch",lv); return 1; } } } fclose(fd); MFSLOG(LOG_NOTICE,"version after applying changelog: %"PRIu64"",v); return 0; }
void test_PASS(int syscall) { int child; subtest("intercept"); do_intercept(syscall, 0); do_release(syscall, 0); subtest("monitor"); do_intercept(syscall, 0); test_monitor(syscall, FALSE); do_start(syscall, -1, 0); test_monitor(syscall, TRUE); do_stop(syscall, -1, 0); test_monitor(syscall, FALSE); do_release(syscall, 0); subtest("monitor & kill monitored process"); do_intercept(syscall, 0); switch (child = fork()) { case -1: assert(0); case 0: // monitor the child process then exit do_start(syscall, -1, 0); test_monitor(syscall, TRUE); exit(0); default: waitpid(child, NULL, 0); // child should have been unmonitored automatically // there is no way to start process with specific pid... do_start(syscall, child, -EINVAL); do_stop(syscall, child, -EINVAL); } do_release(syscall, 0); subtest("monitor all pids"); do_intercept(syscall, 0); test_monitor2(syscall, FALSE, FALSE); do_start(syscall, 0, 0); test_monitor2(syscall, TRUE, TRUE); subtest("stop monitor current pid"); do_stop(syscall, -1, 0); test_monitor2(syscall, FALSE, TRUE); subtest("monitor all -> stop one -> monitor all"); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); subtest("monitor one -> stop all"); do_start(syscall, -1, 0); do_stop(syscall, 0, 0); subtest("monitor all -> stop one -> stop all"); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, 0); subtest("reset"); do_start(syscall, -1, 0); test_monitor2(syscall, TRUE, FALSE); do_stop(syscall, 0, 0); test_monitor2(syscall, FALSE, FALSE); do_release(syscall, 0); }
void test_CDE(int syscall) { //C -EINVAL subtest("Cannot de-intercept a system call that has not been intercepted yet."); do_release(syscall, -EINVAL); subtest("Cannot stop monitoring a pid for a syscall that has not been intercepted."); do_stop(syscall, -1, -EINVAL); do_stop(syscall, 0, -EINVAL); subtest("Cannot start monitoring a pid for that has not been intercepted yet."); do_start(syscall, -1, -EINVAL); do_start(syscall, 0, -EINVAL); do_intercept(syscall, 0); subtest("Cannot start monitoring a pid that is invalid."); do_start(syscall, 1234567, -EINVAL); do_start(syscall, -2, -EINVAL); subtest("Cannot stop monitoring for a pid that is not being monitored."); do_stop(syscall, 0, -EINVAL); do_stop(syscall, -1, -EINVAL); subtest("Cannot stop monitoring for a pid that is blacklisted."); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, -1, -EINVAL); do_stop(syscall, 0, 0); subtest("EINVAL: stop all -> stop all"); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_stop(syscall, 0, -EINVAL); subtest("EINVAL: start one pid -> stop the same pid -> stop all"); do_start(syscall, -1, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, -EINVAL); do_release(syscall, 0); //D -EBUSY do_intercept(syscall, 0); subtest("EBUSY: intercepting a system call that is already intercepted"); do_intercept(syscall, -EBUSY); subtest("EBUSY: monitoring a pid that is being whitelisted"); do_start(syscall, -1, 0); do_start(syscall, -1, -EBUSY); do_stop(syscall, -1, 0); subtest("EBUSY: monitoring a pid that is being monitored globally"); do_start(syscall, 0, 0); do_start(syscall, -1, -EBUSY); do_stop(syscall, 0, 0); subtest("EBUSY: monitoring all pids when all pids are being monitored"); do_start(syscall, 0, 0); do_start(syscall, 0, -EBUSY); do_stop(syscall, 0, 0); subtest("OK: monitoring all pids when some pids are being monitored"); do_start(syscall, -1, 0); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, 0); //E -ENOMEM //If a pid cannot be added to a monitored list, due to no memory being available, an -ENOMEM error code should be returned. // int child; // int res = 0; // while (!res) { // switch (child = fork()) { // case -1://error // assert(0); // case 0: //child // pause(); // default: //parent // res = vsyscall_arg(MY_CUSTOM_SYSCALL, 3, REQUEST_START_MONITORING, syscall, child); // // printf("start monitoring %d: %d\n", child, res); // break; // } // } // test("%d no memory", syscall, res == -ENOMEM); // signal(SIGQUIT, SIG_IGN); // kill(-getpid(), SIGQUIT); do_release(syscall, 0); }
int replay(const char *log_data) { uint64_t fv,lv; //fv = filesystem's version lv = log's version uint32_t ts; uint8_t status; char buff[10000]; char *ptr; char* errormsgs[]={ ERROR_STRINGS }; char *test_ptr; sprintf(buff,"%s",log_data); ptr = buff; //for test test_ptr = buff; fv = shadow_fs_getversion(); GETU64(lv,ptr); if(lv < fv) { MFSLOG(LOG_ERR,"the changelog's verison %lu is smaller than filesystem's version %lu",lv,fv); //more complicated method to ensure consistency } else { status = ERROR_MISMATCH; EAT(ptr,lv,':'); EAT(ptr,lv,' '); GETU32(ts,ptr); EAT(ptr,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(lv,ts,ptr+6); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_aquire(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(lv,ts,ptr+8); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(lv,ts,ptr+13); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(lv,ts,ptr+10); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(lv,ts,ptr+10); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(lv,ts,ptr+4); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(lv,ts,ptr+4); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(lv,ts,ptr+12); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(lv,ts,ptr+7); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; default: MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } /** * if master is down, slave switch, we may missed some metadata * return 0 to let the process continue, otherwise, we will reply the * log forever. * * Dongyang, Zhang */ if (status!=STATUS_OK) { MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s),the log is (%s)",lv,status,errormsgs[status],test_ptr); // syslog(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]); return 1; } fv = shadow_fs_getversion(); if (lv+1!=fv) { MFSLOG(LOG_ERR,"%"PRIu64": version mismatch fsversion:%"PRIu64"",lv,fv); return 1; } } return 0; }
int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); return 0; }