int test_null_parameters() { struct oscap_buffer *s = oscap_buffer_new(); oscap_buffer_append_binary_data(s, NULL, 4); if (oscap_buffer_get_length(s) != 0) { fprintf(stderr, "Appended NULL changed the length of string\n"); return 1; } oscap_buffer_free(NULL); oscap_buffer_free(s); return 0; }
int test_buffer_clear() { struct oscap_buffer *s = oscap_buffer_new(); ASSERT_LENGTH(s, 0); oscap_buffer_clear(s); ASSERT_LENGTH(s, 0); char data = 'A'; oscap_buffer_append_binary_data(s, &data, 1); ASSERT_LENGTH(s, 1); oscap_buffer_clear(s); ASSERT_LENGTH(s, 0); oscap_buffer_free(s); return 0; }
int test_append_binary_data() { static const char* data[] = { "\0", "\0A", "ABC" }; struct oscap_buffer *s = oscap_buffer_new(); ASSERT_LENGTH(s, 0); oscap_buffer_append_binary_data(s, data[0], 1); ASSERT_LENGTH(s, 1); oscap_buffer_append_binary_data(s, data[1], 2); ASSERT_LENGTH(s, 3); oscap_buffer_append_binary_data(s, data[0], 0); // do not increase length ASSERT_LENGTH(s, 3); oscap_buffer_append_binary_data(s, data[2], 3); ASSERT_LENGTH(s, 6); // Check output data int length = oscap_buffer_get_length(s); // length is valid due to previous ASSERT_LENGTH static const char expected_result[] = {'\0', '\0', 'A', 'A', 'B', 'C'}; const char* result = oscap_buffer_get_raw(s); for (int i = 0; i < length; ++i) { char expected = expected_result[i]; char got = result[i]; if ( expected != got ) { fprintf(stderr, "Invalid character at index %d, expected %x and got %x\n", i, expected, got); return 1; } } return 0; }
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; }