int probe_main(probe_ctx *ctx, void *probe_arg) { SEXP_t *unit_entity, *probe_in, *property_entity; oval_version_t oval_version; probe_in = probe_ctx_getobject(ctx); oval_version = probe_obj_get_schema_version(probe_in); if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) { // OVAL 5.10 and less return PROBE_EOPNOTSUPP; } unit_entity = probe_obj_getent(probe_in, "unit", 1); property_entity = probe_obj_getent(probe_in, "property", 1); DBusError dbus_error; DBusConnection *dbus_conn; dbus_error_init(&dbus_error); dbus_conn = connect_dbus(); if (dbus_conn == NULL) { dbus_error_free(&dbus_error); SEXP_free(property_entity); SEXP_free(unit_entity); return PROBE_ESYSTEM; } struct unit_callback_vars vars; vars.dbus_conn = dbus_conn; vars.ctx = ctx; vars.unit_entity = unit_entity; vars.property_entity = property_entity; get_all_systemd_units(dbus_conn, unit_callback, &vars); SEXP_free(unit_entity); SEXP_free(property_entity); dbus_error_free(&dbus_error); disconnect_dbus(dbus_conn); return 0; }
int probe_main(probe_ctx *ctx, void *arg) { SEXP_t *obj, *ent; obj = probe_ctx_getobject(ctx); over = probe_obj_get_schema_version(obj); ent = probe_obj_getent(obj, "command", 1); if (ent == NULL) { return PROBE_ENOVAL; } if (read_process(ent, ctx)) { SEXP_free(ent); return PROBE_EACCESS; } SEXP_free(ent); return 0; }
int probe_main(probe_ctx *ctx, void *probe_arg) { int probe_ret = 0; SEXP_t *mnt_entity, *mnt_opval, *mnt_entval, *probe_in; char mnt_path[PATH_MAX]; oval_operation_t mnt_op; FILE *mnt_fp; oval_version_t obj_over; #if defined(PROC_CHECK) && defined(__linux__) int mnt_fd; struct statfs stfs; mnt_fd = open(MTAB_PATH, O_RDONLY); if (mnt_fd < 0) return (PROBE_ESYSTEM); if (fstatfs(mnt_fd, &stfs) != 0) { close(mnt_fd); return (PROBE_ESYSTEM); } if (stfs.f_type != PROC_SUPER_MAGIC) { close(mnt_fd); return (PROBE_EFATAL); } mnt_fp = fdopen(mnt_fd, "r"); if (mnt_fp == NULL) { close(mnt_fd); return (PROBE_ESYSTEM); } #else mnt_fp = fopen(MTAB_PATH, "r"); if (mnt_fp == NULL) return (PROBE_ESYSTEM); #endif probe_in = probe_ctx_getobject(ctx); obj_over = probe_obj_get_schema_version(probe_in); mnt_entity = probe_obj_getent(probe_in, "mount_point", 1); if (mnt_entity == NULL) { fclose(mnt_fp); return (PROBE_ENOENT); } mnt_opval = probe_ent_getattrval(mnt_entity, "operation"); if (mnt_opval != NULL) { mnt_op = (oval_operation_t)SEXP_number_geti(mnt_opval); SEXP_free(mnt_opval); } else mnt_op = OVAL_OPERATION_EQUALS; mnt_entval = probe_ent_getval(mnt_entity); if (!SEXP_stringp(mnt_entval)) { SEXP_free(mnt_entval); SEXP_free(mnt_entity); fclose(mnt_fp); return (PROBE_EINVAL); } SEXP_string_cstr_r(mnt_entval, mnt_path, sizeof mnt_path); SEXP_free(mnt_entval); SEXP_free(mnt_entity); if (mnt_fp != NULL) { char buffer[MTAB_LINE_MAX]; struct mntent mnt_ent, *mnt_entp; pcre *re = NULL; const char *estr = NULL; int eoff = -1; #if defined(HAVE_BLKID_GET_TAG_VALUE) blkid_cache blkcache; if (blkid_get_cache(&blkcache, NULL) != 0) { endmntent(mnt_fp); return (PROBE_EUNKNOWN); } #endif if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) { re = pcre_compile(mnt_path, PCRE_UTF8, &estr, &eoff, NULL); if (re == NULL) { endmntent(mnt_fp); return (PROBE_EINVAL); } } while ((mnt_entp = getmntent_r(mnt_fp, &mnt_ent, buffer, sizeof buffer)) != NULL) { if (strcmp(mnt_entp->mnt_type, "rootfs") == 0) continue; if (mnt_op == OVAL_OPERATION_EQUALS) { if (strcmp(mnt_entp->mnt_dir, mnt_path) == 0) { #if defined(HAVE_BLKID_GET_TAG_VALUE) collect_item(ctx, obj_over, mnt_entp, blkcache); #else collect_item(ctx, obj_over, mnt_entp); #endif break; } } else if (mnt_op == OVAL_OPERATION_NOT_EQUAL) { if (strcmp(mnt_entp->mnt_dir, mnt_path) != 0) { if ( #if defined(HAVE_BLKID_GET_TAG_VALUE) collect_item(ctx, obj_over, mnt_entp, blkcache) #else collect_item(ctx, obj_over, mnt_entp) #endif != 0) break; } } else if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) { int rc; rc = pcre_exec(re, NULL, mnt_entp->mnt_dir, strlen(mnt_entp->mnt_dir), 0, 0, NULL, 0); if (rc == 0) { if ( #if defined(HAVE_BLKID_GET_TAG_VALUE) collect_item(ctx, obj_over, mnt_entp, blkcache) #else collect_item(ctx, obj_over, mnt_entp) #endif != 0) break; } /* XXX: check for pcre_exec error */ } } endmntent(mnt_fp); if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) pcre_free(re); } return (probe_ret); }
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx) { int err = 1, max_cap_id; DIR *d; struct dirent *ent; oval_version_t oval_version; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx)); if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) { max_cap_id = OVAL_5_8_MAX_CAP_ID; } else { max_cap_id = OVAL_5_11_MAX_CAP_ID; } struct oscap_buffer *cmdline_buffer = oscap_buffer_new(); char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>" cmd_buffer[0] = '['; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL; // Skip non-process58 dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '[' sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; const char* cmd; if (state == 'Z') { // zombie cmd = make_defunc_str(cmd_buffer); } else { snprintf(buf, 32, "/proc/%d/cmdline", pid); if (get_process_cmdline(buf, cmdline_buffer)) { cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline } else { cmd = cmd_buffer + 1; } } err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); pid_sexp = SEXP_number_newu_32(pid); if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) && (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE) ) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command_line = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; r.exec_shield = (get_exec_shield_status(pid) > 0); selinux_domain_label = get_selinux_label(pid); r.selinux_domain_label = selinux_domain_label; posix_capabilities = get_posix_capability(pid, max_cap_id); r.posix_capability = posix_capabilities; r.session_id = session; get_uids(pid, &r); report_finding(&r, ctx); if (selinux_domain_label != NULL) free(selinux_domain_label); if (posix_capabilities != NULL) { char **posix_capabilities_p = posix_capabilities; while (*posix_capabilities_p) free(*posix_capabilities_p++); free(posix_capabilities); } } SEXP_free(cmd_sexp); SEXP_free(pid_sexp); } closedir(d); oscap_buffer_free(cmdline_buffer); return err; }