/** * Validate a given filesystem service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_filesystem(Service_T s) { char *p; char path_buf[PATH_MAX+1]; Filesystem_T td; struct stat stat_buf; ASSERT(s); p = s->path; /* We need to resolve symbolic link so if it points to device, we'll be able to find it in mnttab */ if (lstat(s->path, &stat_buf) != 0) { Event_post(s, Event_Nonexist, STATE_FAILED, s->action_NONEXIST, "filesystem doesn't exist"); return FALSE; } if (S_ISLNK(stat_buf.st_mode)) { if (! realpath(s->path, path_buf)) { Event_post(s, Event_Nonexist, STATE_FAILED, s->action_NONEXIST, "filesystem symbolic link error -- %s", STRERROR); return FALSE; } p = path_buf; Event_post(s, Event_Nonexist, STATE_SUCCEEDED, s->action_NONEXIST, "filesystem symbolic link %s -> %s", s->path, p); if (stat(p, &stat_buf) != 0) { Event_post(s, Event_Nonexist, STATE_FAILED, s->action_NONEXIST, "filesystem doesn't exist"); return FALSE; } } Event_post(s, Event_Nonexist, STATE_SUCCEEDED, s->action_NONEXIST, "filesystem exists"); s->inf->st_mode = stat_buf.st_mode; s->inf->st_uid = stat_buf.st_uid; s->inf->st_gid = stat_buf.st_gid; if (!filesystem_usage(s->inf, p)) { Event_post(s, Event_Data, STATE_FAILED, s->action_DATA, "unable to read filesystem %s state", p); return FALSE; } s->inf->priv.filesystem.inode_percent = s->inf->priv.filesystem.f_files > 0 ? (int)((1000.0 * (s->inf->priv.filesystem.f_files - s->inf->priv.filesystem.f_filesfree)) / (float)s->inf->priv.filesystem.f_files) : 0; s->inf->priv.filesystem.space_percent = s->inf->priv.filesystem.f_blocks > 0 ? (int)((1000.0 * (s->inf->priv.filesystem.f_blocks - s->inf->priv.filesystem.f_blocksfree)) / (float)s->inf->priv.filesystem.f_blocks) : 0; s->inf->priv.filesystem.inode_total = s->inf->priv.filesystem.f_files - s->inf->priv.filesystem.f_filesfree; s->inf->priv.filesystem.space_total = s->inf->priv.filesystem.f_blocks - s->inf->priv.filesystem.f_blocksfreetotal; Event_post(s, Event_Data, STATE_SUCCEEDED, s->action_DATA, "succeeded getting filesystem statistic for %s", p); if (s->perm) check_perm(s); if (s->uid) check_uid(s); if (s->gid) check_gid(s); check_filesystem_flags(s); if (s->filesystemlist) for (td = s->filesystemlist; td; td = td->next) check_filesystem_resources(s, td); return TRUE; }
/* * Saves extension list of media file */ asmlinkage long sys_set_media_ext(const char __user *mediaExtList) { long len, rc = 0; uid_t uid; /* check uid if it's not root(0) nor system(1000) */ uid = current_uid(); if (check_uid(uid)) { printk(KERN_ERR "%s: %s(%u) not permitted.\n", __func__, current->comm, uid); return -EPERM; } mutex_lock(&media_ext_list_lock); /* * The media file extension list set on each boot-up time * and never set again while runtime. is_savedfileExtList_set * is a global flag to check whether the list has been set or not. * If it's already set, this function just return 0 for success. */ if (is_savedfileExtList_set) { printk(KERN_INFO "%s: the file list already set.\n", __func__); goto out; } /* check if mediaExtList is not userspace */ if (!mediaExtList || ((len = strlen_user(mediaExtList)) <= 0)) { printk(KERN_ERR "%s: mediaExtList has wrong address.\n", __func__); rc = -EFAULT; goto out; } /* check overflow */ if (len >= MAX_MEDIA_EXT_LENGTH) { printk(KERN_ERR "%s: mediaExtList is too large.\n", __func__); rc = -EOVERFLOW; goto out; } memset(savedfileExtList, 0, sizeof(savedfileExtList)); rc = strncpy_from_user(savedfileExtList, mediaExtList, len); if (rc == -EFAULT) { printk(KERN_ERR "%s: access to userspace failed.\n", __func__); goto out; } is_savedfileExtList_set = true; /* set return value 0 for success */ rc = 0; /* for debuging */ /* printk("%s :: savedfileExtList(%d bytes): %s\n", __func__, strlen(savedfileExtList), savedfileExtList); */ out: mutex_unlock(&media_ext_list_lock); return rc; }
/** * Validate a given file service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_file(Service_T s) { struct stat stat_buf; ASSERT(s); if (stat(s->path, &stat_buf) != 0) { Event_post(s, Event_Nonexist, STATE_FAILED, s->action_NONEXIST, "file doesn't exist"); return FALSE; } else { s->inf->st_mode = stat_buf.st_mode; if (s->inf->priv.file.st_ino == 0) { s->inf->priv.file.st_ino_prev = stat_buf.st_ino; s->inf->priv.file.readpos = stat_buf.st_size; } else s->inf->priv.file.st_ino_prev = s->inf->priv.file.st_ino; s->inf->priv.file.st_ino = stat_buf.st_ino; s->inf->st_uid = stat_buf.st_uid; s->inf->st_gid = stat_buf.st_gid; s->inf->priv.file.st_size = stat_buf.st_size; s->inf->timestamp = MAX(stat_buf.st_mtime, stat_buf.st_ctime); DEBUG("'%s' file exists check succeeded\n", s->name); Event_post(s, Event_Nonexist, STATE_SUCCEEDED, s->action_NONEXIST, "file exist"); } if (!S_ISREG(s->inf->st_mode)) { Event_post(s, Event_Invalid, STATE_FAILED, s->action_INVALID, "is not a regular file"); return FALSE; } else { DEBUG("'%s' is a regular file\n", s->name); Event_post(s, Event_Invalid, STATE_SUCCEEDED, s->action_INVALID, "is a regular file"); } if (s->checksum) check_checksum(s); if (s->perm) check_perm(s); if (s->uid) check_uid(s); if (s->gid) check_gid(s); if (s->sizelist) check_size(s); if (s->timestamplist) check_timestamp(s); if (s->matchlist) check_match(s); return TRUE; }
/* Implement proc_setexecdata as described in <hurd/process.defs>. */ kern_return_t S_proc_setexecdata (struct proc *p, mach_port_t *ports, size_t nports, int *ints, size_t nints) { int i; struct execdata_notify *n; mach_port_t *std_port_array_new; int *std_int_array_new; if (!p) return EOPNOTSUPP; if (!check_uid (p, 0)) return EPERM; /* Allocate memory up front. */ std_port_array_new = malloc (sizeof (mach_port_t) * nports); if (! std_port_array_new) return ENOMEM; std_int_array_new = malloc (sizeof (int) * nints); if (! std_int_array_new) { free (std_port_array_new); return ENOMEM; } if (std_port_array) { for (i = 0; i < n_std_ports; i++) mach_port_deallocate (mach_task_self (), std_port_array[i]); free (std_port_array); } if (std_int_array) free (std_int_array); std_port_array = std_port_array_new; n_std_ports = nports; memcpy (std_port_array, ports, sizeof (mach_port_t) * nports); std_int_array = std_int_array_new; n_std_ints = nints; memcpy (std_int_array, ints, sizeof (int) * nints); for (n = execdata_notifys; n; n = n->next) exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, n_std_ports, std_int_array, n_std_ints); return 0; }
/** * Validate a given directory service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_directory(Service_T s) { struct stat stat_buf; char report[STRLEN]= {0}; if(stat(s->path, &stat_buf) != 0) { if(! s->event_handled) { Event_post(s, EVENT_START, "Event: directory '%s' doesn't exist\n", s->name); s->event_handled= TRUE; } return FALSE; } else { s->event_handled= FALSE; } if(!S_ISDIR(stat_buf.st_mode)) { if(!s->event_handled) { Event_post(s, EVENT_UNMONITOR, "Event: '%s' is not directory\n", s->name); s->event_handled= TRUE; } return FALSE; } else { s->event_handled= FALSE; } if(check_perm(s, stat_buf.st_mode, report)) { s->perm->event_flag= TRUE; if(! eval_actions(s->perm->action, s, report, "permission", EVENT_PERMISSION)) return FALSE; } if(check_uid(s, stat_buf.st_uid, report)) { s->uid->event_flag= TRUE; if(! eval_actions(s->uid->action, s, report, "uid", EVENT_UID)) return FALSE; } if(check_gid(s, stat_buf.st_gid, report)) { s->gid->event_flag= TRUE; if(! eval_actions(s->gid->action, s, report, "gid", EVENT_GID)) return FALSE; } if(!check_timestamps(s)) return FALSE; return TRUE; }
/* * Saves extension list of media file */ long set_media_ext(const char *media_ext_list) { long len, rc = 0; uid_t uid; /* check uid if it's not root(0) nor system(1000) */ uid = current_uid(); if (check_uid(uid)) { pr_err("%s: %s(%u) not permitted.\n", __func__, current->comm, uid); return -EPERM; } mutex_lock(&media_ext_list_lock); /* * The media file extension list set on each boot-up time * and never set again while runtime. is_saved_file_ext_list_set * is a global flag to check whether the list has been set or not. * If it's already set, this function just return 0 for success. */ if (is_saved_file_ext_list_set) { pr_info("%s: the file list already set.\n", __func__); goto out; } /* check if media_ext_list is not userspace */ if (!media_ext_list || ((len = strlen(media_ext_list)) <= 0)) { pr_err("%s: media_ext_list is Null value.\n", __func__); rc = -EFAULT; goto out; } /* check overflow */ if (len >= MAX_MEDIA_EXT_LENGTH) { pr_err("%s: media_ext_list is too large.\n", __func__); rc = -EOVERFLOW; goto out; } memset(saved_file_ext_list, 0, sizeof(saved_file_ext_list)); strncpy(saved_file_ext_list, media_ext_list, len); is_saved_file_ext_list_set = true; /* set return value 0 for success */ rc = 0; out: mutex_unlock(&media_ext_list_lock); return rc; }
/* Implement proc_getprivports as described in <hurd/process.defs>. */ kern_return_t S_proc_getprivports (struct proc *p, mach_port_t *hostpriv, mach_port_t *devpriv) { if (!p) return EOPNOTSUPP; if (! check_uid (p, 0)) return EPERM; *hostpriv = master_host_port; *devpriv = master_device_port; return 0; }
/*ARGSUSED*/ static void * check_user_process(void *arg) { DIR *dp; struct dirent *ep; int found; char *me = "check_user_process"; /*CONSTCOND*/ while (1) { (void) sleep(60); found = 0; /* * search the /proc directory and look at each process */ if ((dp = opendir("/proc")) == NULL) { _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_ERROR) (me, "unable to open the /proc directory\n"); continue; } /* for each active process */ while (ep = readdir(dp)) { if (ep->d_name[0] == '.') /* skip . and .. */ continue; if (check_uid(ep->d_name) == 0) { found = 1; break; } } /* * if no process running as the PUN uid found, exit * to kill this PUN */ if (found == 0) { (void) closedir(dp); exit(1); } (void) closedir(dp); } /* NOTREACHED */ /*LINTED E_FUNC_HAS_NO_RETURN_STMT*/ }
/** * Validate a given fifo service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_fifo(Service_T s) { struct stat stat_buf; ASSERT(s); if (stat(s->path, &stat_buf) != 0) { Event_post(s, Event_Nonexist, STATE_FAILED, s->action_NONEXIST, "fifo doesn't exist"); return FALSE; } else { s->inf->st_mode = stat_buf.st_mode; s->inf->st_uid = stat_buf.st_uid; s->inf->st_gid = stat_buf.st_gid; s->inf->timestamp = MAX(stat_buf.st_mtime, stat_buf.st_ctime); DEBUG("'%s' fifo exists check succeeded\n", s->name); Event_post(s, Event_Nonexist, STATE_SUCCEEDED, s->action_NONEXIST, "fifo exist"); } if (!S_ISFIFO(s->inf->st_mode)) { Event_post(s, Event_Invalid, STATE_FAILED, s->action_INVALID, "is not fifo"); return FALSE; } else { DEBUG("'%s' is fifo\n", s->name); Event_post(s, Event_Invalid, STATE_SUCCEEDED, s->action_INVALID, "is fifo"); } if (s->perm) check_perm(s); if (s->uid) check_uid(s); if (s->gid) check_gid(s); if (s->timestamplist) check_timestamp(s); return TRUE; }
/* * Saves whether system property of media encryption is checked */ asmlinkage long sys_set_media_property(int value) { uid_t uid; /* printk("%s :: SystemCall value: %d , propertymediacheck : %d\n", __func__,value,propertyMediaCheck); */ uid = current_uid(); if (check_uid(uid)) { printk(KERN_ERR "%s: %s(%u) not permitted.\n", __func__, current->comm, uid); return -EPERM; } if ((value != 0) && (value != 1)) { printk(KERN_ERR "%s: invalid property.(%d)\n", __func__, value); return -EINVAL; } mutex_lock(&media_ext_list_lock); propertyMediaCheck = value; mutex_unlock(&media_ext_list_lock); return 0; }
/* let's go... */ int main(int argc, char *argv[]) { int c = 0; ctrl_t *ctrl = NULL; /* banner is very important */ banner(); check_argc(argc); ctrl = alloc_structs(); ctrl = set_ctrl_defaults(ctrl); while ((c = getopt(argc, argv, "h:t:s:m:p:vVH")) != -1) { switch (c) { case 'h': check_host(optarg); ctrl->packet->host = convert_host(optarg); break; case 't': check_pkt_type(ctrl, optarg); ctrl->packet->type = (unsigned char) ATOI(optarg); break; case 's': check_shell_mode(ctrl, optarg); ctrl->shell->mode = (unsigned char) ATOI(optarg); break; case 'm': ctrl->packet->payload = optarg; break; case 'p': check_port(ctrl, ATOI(optarg)); ctrl->packet->port = (uint16_t) ATOI(optarg); break; case 'v': ctrl->verbose = VERBOSE; break; case 'V': puts(VERSION); __EXIT_SUCCESS; break; case 'H': usage(); __EXIT_SUCCESS; break; default: __EXIT_FAILURE; } } /* few checks before we can go on */ __VERBOSE_ARGS; check_args(ctrl); check_uid(ctrl); /* install signal handler */ install_signals(); /* let's go */ start_trixd00r(ctrl); end_trixd00r(ctrl); return 0; }
/** * Validate a given file service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_file(Service_T s) { Size_T sl; struct stat stat_buf; char report[STRLEN]= {0}; if(stat(s->path, &stat_buf) != 0) { if(! s->event_handled) { Event_post(s, EVENT_START, "Event: file '%s' doesn't exist\n", s->name); s->event_handled= TRUE; } return FALSE; } else { s->event_handled= TRUE; } if(!S_ISREG(stat_buf.st_mode)) { if(! s->event_handled) { Event_post(s, EVENT_UNMONITOR, "Event: '%s' is not regular file\n", s->name); s->event_handled= TRUE; } return FALSE; } else { s->event_handled= FALSE; } if(check_checksum(s, report)) { s->checksum->event_flag= TRUE; if(! eval_actions(s->checksum->action, s, report, "checksum", EVENT_CHECKSUM)) return FALSE; } if(check_perm(s, stat_buf.st_mode, report)) { s->perm->event_flag= TRUE; if(! eval_actions(s->perm->action, s, report, "permission", EVENT_PERMISSION)) return FALSE; } if(check_uid(s, stat_buf.st_uid, report)) { s->uid->event_flag= TRUE; if(! eval_actions(s->uid->action, s, report, "uid", EVENT_UID)) return FALSE; } if(check_gid(s, stat_buf.st_gid, report)) { s->gid->event_flag= TRUE; if(! eval_actions(s->gid->action, s, report, "gid", EVENT_GID)) return FALSE; } for(sl= s->sizelist; sl; sl= sl->next) { if(!check_size_item(s, sl, (unsigned long)stat_buf.st_size, report)) { if(! sl->event_handled) { /* Turn on the object's event_flag to indicate that the size event * occured on this particular object */ sl->event_flag= TRUE; sl->event_handled= TRUE; /* Turn on the object's * event_handled flag so this * test is not handled in * subsequent poll cycles until * the error condition was reset. */ if(! eval_actions(sl->action, s, report, "size", EVENT_SIZE)) { return FALSE; } } } else { sl->event_handled= FALSE; } } if(!check_timestamps(s)) return FALSE; return TRUE; }
/** * Validate a given device service s. Events are posted according to * its configuration. In case of a fatal event FALSE is returned. */ int check_device(Service_T s) { Device_T td; struct stat stat_buf; char report[STRLEN]= {0}; if(stat(s->path, &stat_buf) != 0) { if(! s->event_handled) { Event_post(s, EVENT_START, "Event: device '%s' doesn't exist\n", s->name); s->event_handled= TRUE; } return FALSE; } else { s->event_handled= FALSE; } if(check_perm(s, stat_buf.st_mode, report)) { s->perm->event_flag= TRUE; if(! eval_actions(s->perm->action, s, report, "permission", EVENT_PERMISSION)) return FALSE; } if(check_uid(s, stat_buf.st_uid, report)) { s->uid->event_flag= TRUE; if(! eval_actions(s->uid->action, s, report, "uid", EVENT_UID)) return FALSE; } if(check_gid(s, stat_buf.st_gid, report)) { s->gid->event_flag= TRUE; if(! eval_actions(s->gid->action, s, report, "gid", EVENT_GID)) return FALSE; } if(!DeviceInfo_Usage(s->devinfo, s->path)) { if(! s->devinfo->event_handled) { Event_post(s, EVENT_START, "Event: unable to read device '%s' state\n", s->path); s->devinfo->event_handled= TRUE; } return FALSE; } else { s->devinfo->event_handled= FALSE; DEBUG("'%s' succeeded getting device statistic for %s\n", s->name, s->path); } /* Test devices */ if(s->devicelist) { for(td= s->devicelist; td; td= td->next) { if(!check_device_resources(s, td, report)) { if(! td->event_handled) { td->event_flag= TRUE; /* Turn on the object's event_flag * to indicate that the resource * event occured on this particular * object */ td->event_handled= TRUE; /* Turn on the object's * event_handled flag so this * test is not handled in * subsequent poll cycles until * the error condition was reset. */ if(! eval_actions(td->action, s, report, "device", EVENT_RESOURCE)) { return FALSE; } } } else { td->event_handled= FALSE; } } } return TRUE; }
void handle_syscall_ret(struct syscallrecord *rec) { struct syscallentry *entry; struct msg_syscallresult scmsg; struct childdata *child = this_child(); unsigned int call; init_msgchildhdr(&scmsg.hdr, SYSCALL_RESULT, pids[child->num], child->num); scmsg.hdr.tp = rec->tp; scmsg.sequence_nr = child->op_nr; scmsg.retval = rec->retval; scmsg.errno_post = rec->errno_post; sendudp((char *) &scmsg, sizeof(scmsg)); call = rec->nr; entry = syscalls[call].entry; if (rec->retval == -1UL) { int err = rec->errno_post; /* only check syscalls that completed. */ //FIXME: how else would we get here? if (rec->state == AFTER) { if (err == ENOSYS) deactivate_enosys(rec, entry, call); entry->failures++; if (err < NR_ERRNOS) { entry->errnos[err]++; } else { // "These should never be seen by user programs." // But trinity isn't a 'normal' user program, we're doing // stuff that libc hides from apps. if (err < 512 || err > 530) printf("errno out of range after doing %s: %d:%s\n", entry->name, err, strerror(err)); } shm->stats.failures++; } } else { handle_success(rec); // Believe me folks, you'll never get bored with winning entry->successes++; shm->stats.successes++; } entry->attempted++; generic_post(entry->arg1type, rec->a1); generic_post(entry->arg2type, rec->a2); generic_post(entry->arg3type, rec->a3); generic_post(entry->arg4type, rec->a4); generic_post(entry->arg5type, rec->a5); generic_post(entry->arg6type, rec->a6); if (entry->post) entry->post(rec); check_uid(); generic_free_arg(rec); }