TEST(stdio_ext, __fsetlocking) { FILE* fp = fopen("/proc/version", "r"); ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY)); ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_BYCALLER)); ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_QUERY)); ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_INTERNAL)); ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY)); fclose(fp); }
TEST(stdio_ext, __fsetlocking_BYCALLER) { // Check if users can use flockfile/funlockfile to protect stdio operations. int old_state = __fsetlocking(stdout, FSETLOCKING_BYCALLER); flockfile(stdout); pthread_t thread; std::atomic<pid_t> pid(0); ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(LockingByCallerHelper), &pid)); WaitUntilThreadSleep(pid); funlockfile(stdout); ASSERT_EQ(0, pthread_join(thread, nullptr)); __fsetlocking(stdout, old_state); }
int security_load_booleans(char *path) { FILE *boolf; char *inbuf; char localbools[BUFSIZ]; size_t len = 0, errors = 0; int val; char name[BUFSIZ]; boolf = fopen(path ? path : selinux_booleans_path(), "r"); if (boolf == NULL) goto localbool; __fsetlocking(boolf, FSETLOCKING_BYCALLER); while (getline(&inbuf, &len, boolf) > 0) { int ret = process_boolean(inbuf, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) if (security_set_boolean(name, val) < 0) { errors++; } } fclose(boolf); localbool: snprintf(localbools, sizeof(localbools), "%s.local", (path ? path : selinux_booleans_path())); boolf = fopen(localbools, "r"); if (boolf != NULL) { int ret; __fsetlocking(boolf, FSETLOCKING_BYCALLER); while (getline(&inbuf, &len, boolf) > 0) { ret = process_boolean(inbuf, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) if (security_set_boolean(name, val) < 0) { errors++; } } fclose(boolf); } if (security_commit_booleans() < 0) return -1; if (errors) errno = EINVAL; return errors ? -1 : 0; }
static int write_string_file_atomic( const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; int r; assert(fn); assert(line); r = fopen_temporary(fn, &f, &p); if (r < 0) return r; (void) __fsetlocking(f, FSETLOCKING_BYCALLER); (void) fchmod_umask(fileno(f), 0644); r = write_string_stream_ts(f, line, flags, ts); if (r < 0) goto fail; if (rename(p, fn) < 0) { r = -errno; goto fail; } return 0; fail: (void) unlink(p); return r; }
static void get_boot_time(void) { char buf[100]; FILE *sf; int line; boot = 0; sf = fopen("/proc/stat", "rt"); if (sf == NULL) return; line = 0; __fsetlocking(sf, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), sf)) { if (line == 0) { line++; continue; } if (memcmp(buf, "btime", 5) == 0) { sscanf(buf, "btime %lu", &boot); break; } } fclose(sf); }
int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid) { if (dwfl == NULL) return -1; /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */ GElf_Addr sysinfo_ehdr = 0; int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr); if (result != 0) return result; char *fname; if (asprintf (&fname, PROCMAPSFMT, pid) < 0) return ENOMEM; FILE *f = fopen (fname, "r"); free (fname); if (f == NULL) return errno; (void) __fsetlocking (f, FSETLOCKING_BYCALLER); result = proc_maps_report (dwfl, f, sysinfo_ehdr, pid); fclose (f); return result; }
int generator_open_unit_file( const char *dest, const char *source, const char *name, FILE **file) { const char *unit; FILE *f; unit = strjoina(dest, "/", name); f = fopen(unit, "wxe"); if (!f) { if (source && errno == EEXIST) return log_error_errno(errno, "Failed to create unit file %s, as it already exists. Duplicate entry in %s?", unit, source); else return log_error_errno(errno, "Failed to create unit file %s: %m", unit); } (void) __fsetlocking(f, FSETLOCKING_BYCALLER); fprintf(f, "# Automatically generated by %s\n\n", program_invocation_short_name); *file = f; return 0; }
static int get_bounding_set(void) { char buf[64]; FILE *f; snprintf(buf, sizeof(buf), "/proc/%u/status", m.hdr.pid ? m.hdr.pid : #ifdef HAVE_SYSCALL_H (unsigned)syscall(__NR_gettid)); #else (unsigned)getpid(); #endif f = fopen(buf, "re"); if (f == NULL) return -1; __fsetlocking(f, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), f)) { if (strncmp(buf, "CapB", 4)) continue; sscanf(buf, "CapBnd: %08x%08x", &m.bounds[1], &m.bounds[0]); fclose(f); return 0; } fclose(f); return -1; }
static int get_uids(int pid, struct result_info *r) { char buf[100]; FILE *sf; r->ruid = -1; r->user_id = -1; snprintf(buf, sizeof(buf), "/proc/%d/status", pid); sf = fopen(buf, "rt"); if (sf) { int line = 0; __fsetlocking(sf, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), sf)) { if (line == 0) { line++; continue; } if (memcmp(buf, "Uid:", 4) == 0) { sscanf(buf, "Uid: %d %d", &r->ruid, &r->user_id); break; } } fclose(sf); } return 0; }
static int smackfs_exists(void) { int exists = 0; FILE *fp = NULL; char *buf = NULL; size_t len; ssize_t num; /* Fail as SmackFS would exist since we are checking mounts after * this. */ fp = fopen("/proc/filesystems", "r"); if (!fp) return 1; __fsetlocking(fp, FSETLOCKING_BYCALLER); num = getline(&buf, &len, fp); while (num != -1) { if (strstr(buf, SMACKFS)) { exists = 1; break; } num = getline(&buf, &len, fp); } free(buf); fclose(fp); return exists; }
int write_env_file(const char *fname, char **l) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; char **i; int r; assert(fname); r = fopen_temporary(fname, &f, &p); if (r < 0) return r; (void) __fsetlocking(f, FSETLOCKING_BYCALLER); (void) fchmod_umask(fileno(f), 0644); STRV_FOREACH(i, l) write_env_var(f, *i); r = fflush_and_check(f); if (r >= 0) { if (rename(p, fname) >= 0) return 0; r = -errno; } unlink(p); return r; }
/* General function to get information about memory status from proc filesystem. */ static long int internal_function phys_pages_info (const char *format) { char buffer[8192]; long int result = -1; /* If we haven't found an appropriate entry return 1. */ FILE *fp = fopen ("/proc/meminfo", "rc"); if (fp != NULL) { /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); result = 0; /* Read all lines and count the lines starting with the string "processor". We don't have to fear extremely long lines since the kernel will not generate them. 8192 bytes are really enough. */ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) if (sscanf (buffer, format, &result) == 1) { result /= (__getpagesize () / 1024); break; } fclose (fp); } if (result == -1) /* We cannot get the needed value: signal an error. */ __set_errno (ENOSYS); return result; }
int main (int argc, char *argv[]) { int remaining; int result = 0; /* Make memory leak detection possible. */ mtrace (); /* We use no threads here which can interfere with handling a stream. */ __fsetlocking (stdin, FSETLOCKING_BYCALLER); __fsetlocking (stdout, FSETLOCKING_BYCALLER); __fsetlocking (stderr, FSETLOCKING_BYCALLER); /* Set locale. */ setlocale (LC_ALL, ""); /* Make sure the message catalog can be found. */ bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); /* Initialize the message catalog. */ textdomain (PACKAGE_TARNAME); /* Parse and process arguments. */ argp_parse (&argp, argc, argv, 0, &remaining, NULL); /* Tell the library which version we are expecting. */ elf_version (EV_CURRENT); if (remaining == argc) /* The user didn't specify a name so we use a.out. */ result = process_file ("a.out"); else /* Process all the remaining files. */ do result |= process_file (argv[remaining]); while (++remaining < argc); /* Print the total sizes but only if the output format is BSD and at least one file has been correctly read (i.e., we recognized the class). */ if (totals && format == format_bsd && totals_class != 0) show_bsd_totals (); return result; }
static void FopenFgetsFclose(benchmark::State& state, bool no_locking) { char buf[1024]; while (state.KeepRunning()) { FILE* fp = fopen("/proc/version", "re"); if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER); if (fgets(buf, sizeof(buf), fp) == nullptr) abort(); fclose(fp); } }
static void FopenFgetsFclose(int iters, bool no_locking) { char buf[1024]; for (int i = 0; i < iters; ++i) { FILE* fp = fopen("/proc/version", "re"); if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER); fgets(buf, sizeof(buf), fp); fclose(fp); } }
int main (int argc, char *argv[]) { int remaining; int result = 0; /* Make memory leak detection possible. */ mtrace (); /* We use no threads here which can interfere with handling a stream. */ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); /* Set locale. */ (void) setlocale (LC_ALL, ""); /* Make sure the message catalog can be found. */ (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); /* Initialize the message catalog. */ (void) textdomain (PACKAGE_TARNAME); /* Parse and process arguments. */ (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); /* Tell the library which version we are expecting. */ (void) elf_version (EV_CURRENT); if (remaining == argc) /* The user didn't specify a name so we use a.out. */ result = process_file ("a.out", false); else { /* Process all the remaining files. */ const bool more_than_one = remaining + 1 < argc; do result |= process_file (argv[remaining], more_than_one); while (++remaining < argc); } return result; }
int main (int argc, char *argv[]) { int remaining; /* Set locale. */ (void) setlocale (LC_ALL, ""); Dwfl *dwfl = NULL; (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl); assert (dwfl != NULL); int result = 0; /* Now handle the addresses. In case none are given on the command line, read from stdin. */ if (remaining == argc) { /* We use no threads here which can interfere with handling a stream. */ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); char *buf = NULL; size_t len = 0; while (!feof_unlocked (stdin)) { if (getline (&buf, &len, stdin) < 0) break; char *endp; uintmax_t addr = strtoumax (buf, &endp, 0); if (endp != buf) result |= handle_address (addr, dwfl); else result = 1; } free (buf); } else { do { char *endp; uintmax_t addr = strtoumax (argv[remaining], &endp, 0); if (endp != argv[remaining]) result |= handle_address (addr, dwfl); else result = 1; } while (++remaining < argc); } dwfl_end (dwfl); return result; }
int main (int argc, char *argv[]) { /* Make memory leak detection possible. */ mtrace (); /* We use no threads here which can interfere with handling a stream. */ (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER); /* Set locale. */ (void) setlocale (LC_ALL, ""); /* Make sure the message catalog can be found. */ (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); /* Initialize the message catalog. */ (void) textdomain (PACKAGE_TARNAME); /* Parse and process arguments. */ int remaining; (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL); /* Tell the library which version we are expecting. */ (void) elf_version (EV_CURRENT); /* There must at least be one more parameter specifying the archive. */ if (remaining == argc) { error (0, 0, gettext ("Archive name required")); argp_help (&argp, stderr, ARGP_HELP_SEE, "ranlib"); exit (EXIT_FAILURE); } /* We accept the names of multiple archives. */ int status = 0; do status |= handle_file (argv[remaining]); while (++remaining < argc); return status; }
int main (int argc __attribute__ ((unused)), char **argv) { /* We use no threads here which can interfere with handling a stream. */ __fsetlocking (stdin, FSETLOCKING_BYCALLER); __fsetlocking (stdout, FSETLOCKING_BYCALLER); __fsetlocking (stderr, FSETLOCKING_BYCALLER); /* Set locale. */ (void) setlocale (LC_ALL, ""); elf_version (EV_CURRENT); pid_t pid = fork (); switch (pid) { case -1: abort (); case 0:; long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); assert (errno == 0); assert (l == 0); cleanup_13_main (); abort (); default: break; } errno = 0; int status; pid_t got = waitpid (pid, &status, 0); assert (errno == 0); assert (got == pid); assert (WIFSTOPPED (status)); assert (WSTOPSIG (status) == SIGABRT); Dwfl *dwfl = pid_to_dwfl (pid); dwfl_getthreads (dwfl, thread_callback, NULL); /* There is an exit (0) call if we find the "main" frame, */ error (1, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1)); }
static int process_file(const char *path, const char *suffix, struct selabel_handle *rec, const char *prefix) { FILE *fp; struct stat sb; unsigned int lineno; size_t line_len = 0; char *line_buf = NULL; int rc; char stack_path[PATH_MAX + 1]; /* append the path suffix if we have one */ if (suffix) { rc = snprintf(stack_path, sizeof(stack_path), "%s.%s", path, suffix); if (rc >= (int)sizeof(stack_path)) { errno = ENAMETOOLONG; return -1; } path = stack_path; } /* Open the specification file. */ if ((fp = fopen(path, "r")) == NULL) return -1; __fsetlocking(fp, FSETLOCKING_BYCALLER); if (fstat(fileno(fp), &sb) < 0) return -1; if (!S_ISREG(sb.st_mode)) { errno = EINVAL; return -1; } rc = load_mmap(rec, path, &sb); if (rc == 0) goto out; /* * Then do detailed validation of the input and fill the spec array */ lineno = 0; rc = 0; while (getline(&line_buf, &line_len, fp) > 0) { rc = process_line(rec, path, prefix, line_buf, ++lineno); if (rc) goto out; } out: free(line_buf); fclose(fp); return rc; }
static int process_file(char *filename) { log_fd = fopen(filename, "rm"); if (log_fd == NULL) { fprintf(stderr, "Error opening %s (%s)\n", filename, strerror(errno)); return 1; } __fsetlocking(log_fd, FSETLOCKING_BYCALLER); return process_log_fd(filename); }
static int read_packet(llist *l, probe_ctx *ctx, oval_schema_version_t over) { int line = 0; FILE *f; char buf[256]; void *s; int refcnt, sk_type, ifindex, running; unsigned long inode; unsigned rmem, uid, proto_num; struct interface_t interface; f = fopen("/proc/net/packet", "rt"); if (f == NULL) { if (errno != ENOENT) return 1; else return 0; } __fsetlocking(f, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), f)) { if (line == 0) { line++; continue; } /* follow structure from net/packet/af_packet.c */ sscanf(buf, "%p %d %d %04x %d %d %u %u %lu\n", &s, &refcnt, &sk_type, &proto_num, &ifindex, &running, &rmem, &uid, &inode ); if (list_find_inode(l, inode) && get_interface(ifindex, &interface)) { struct result_info r; SEXP_t *r0; dI("Have interface_name: %s, hw_address: %s\n", interface.interface_name, interface.hw_address); r0 = SEXP_string_newf("%s", interface.interface_name); if (probe_entobj_cmp(interface_name_ent, r0) != OVAL_RESULT_TRUE) { SEXP_free(r0); continue; } SEXP_free(r0); r.interface_name = interface.interface_name; r.protocol = oscap_enum_to_string(ProtocolType, proto_num); r.hw_address = interface.hw_address; report_finding(&r, l, ctx, over); } } fclose(f); return 0; }
static int read_tcp(const char *proc, const char *type, llist *l, probe_ctx *ctx) { int line = 0; FILE *f; char buf[256]; unsigned long rxq, txq, time_len, retr, inode; unsigned local_port, rem_port, uid; int d, state, timer_run, timeout; char rem_addr[128], local_addr[128], more[512]; f = fopen(proc, "rt"); if (f == NULL) { if (errno != ENOENT) return 1; else return 0; } __fsetlocking(f, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), f)) { if (line == 0) { line++; continue; } more[0] = 0; sscanf(buf, "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X " "%lX:%lX %X:%lX %lX %d %d %lu %512s\n", &d, local_addr, &local_port, rem_addr, &rem_port, &state, &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more); char src[NI_MAXHOST], dest[NI_MAXHOST]; addr_convert(local_addr, src, NI_MAXHOST); addr_convert(rem_addr, dest, NI_MAXHOST); dI("Have tcp port: %s:%u\n", src, local_port); if (eval_data(type, src, local_port)) { struct result_info r; r.proto = type; r.laddr = src; r.lport = local_port; r.raddr = dest; r.rport = rem_port; if (list_find_inode(l, inode)) { report_finding(&r, l, ctx); } else { report_finding(&r, NULL, ctx); } } } fclose(f); return 0; }
int parse_open(semanage_handle_t * handle, parse_info_t * info) { info->file_stream = fopen(info->filename, "r"); if (!info->file_stream && (errno != ENOENT)) { ERR(handle, "could not open file %s: %s", info->filename, strerror(errno)); return STATUS_ERR; } if (info->file_stream) __fsetlocking(info->file_stream, FSETLOCKING_BYCALLER); return STATUS_SUCCESS; }
int read_full_file(const char *fn, char **contents, size_t *size) { _cleanup_fclose_ FILE *f = NULL; assert(fn); assert(contents); f = fopen(fn, "re"); if (!f) return -errno; (void) __fsetlocking(f, FSETLOCKING_BYCALLER); return read_full_stream(f, contents, size); }
static enum nss_status internal_setgrent (ent_t *ent) { enum nss_status status = NSS_STATUS_SUCCESS; ent->files = TRUE; if (ni == NULL) init_nss_interface (); if (ent->blacklist.data != NULL) { ent->blacklist.current = 1; ent->blacklist.data[0] = '|'; ent->blacklist.data[1] = '\0'; } else ent->blacklist.current = 0; ent->stream = fopen ("/etc/group", "rm"); if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else { /* We have to make sure the file is `closed on exec'. */ int result, flags; result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, 0); if (result >= 0) { flags |= FD_CLOEXEC; result = fcntl (fileno_unlocked (ent->stream), F_SETFD, flags); } if (result < 0) { /* Something went wrong. Close the stream and return a failure. */ fclose (ent->stream); ent->stream = NULL; status = NSS_STATUS_UNAVAIL; } else /* We take care of locking ourself. */ __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); } return status; }
int __get_nprocs () { char buffer[8192]; int result = 1; /* XXX Here will come a test for the new system call. */ /* The /proc/stat format is more uniform, use it by default. */ FILE *fp = fopen ("/proc/stat", "rc"); if (fp != NULL) { /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); result = 0; while (fgets_unlocked (buffer, sizeof (buffer), fp) != NULL) if (strncmp (buffer, "cpu", 3) == 0 && isdigit (buffer[3])) ++result; fclose (fp); } else { fp = fopen ("/proc/cpuinfo", "rc"); if (fp != NULL) { /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); GET_NPROCS_PARSER (fp, buffer, result); fclose (fp); } } return result; }
int init_smackfs_mnt(void) { char *buf = NULL; char *startp; char *endp; FILE *fp = NULL; size_t len; ssize_t num; int ret = 0; if (smackfs_mnt || verify_smackfs_mnt(SMACKFSMNT) == 0 || verify_smackfs_mnt(OLDSMACKFSMNT) == 0) return 0; if (!smackfs_exists()) return -1; fp = fopen("/proc/mounts", "r"); if (!fp) return -1; __fsetlocking(fp, FSETLOCKING_BYCALLER); while ((num = getline(&buf, &len, fp)) != -1) { startp = strchr(buf, ' '); if (!startp) { ret = -1; break; } startp++; endp = strchr(startp, ' '); if (!endp) { ret = -1; break; } if (!strncmp(endp + 1, SMACKFS" ", strlen(SMACKFS) + 1)) { *endp = '\0'; ret = verify_smackfs_mnt(startp); break; } } free(buf); fclose(fp); return ret; }
/* On some architectures it is possible to distinguish between configured and active cpus. */ int __get_nprocs_conf () { /* XXX Here will come a test for the new system call. */ /* Try to use the sysfs filesystem. It has actual information about online processors. */ DIR *dir = __opendir ("/sys/devices/system/cpu"); if (dir != NULL) { int count = 0; struct dirent64 *d; while ((d = __readdir64 (dir)) != NULL) /* NB: the sysfs has d_type support. */ if (d->d_type == DT_DIR && strncmp (d->d_name, "cpu", 3) == 0) { char *endp; unsigned long int nr = strtoul (d->d_name + 3, &endp, 10); if (nr != ULONG_MAX && endp != d->d_name + 3 && *endp == '\0') ++count; } __closedir (dir); return count; } int result = 1; #ifdef GET_NPROCS_CONF_PARSER /* If we haven't found an appropriate entry return 1. */ FILE *fp = fopen ("/proc/cpuinfo", "rce"); if (fp != NULL) { char buffer[8192]; /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); GET_NPROCS_CONF_PARSER (fp, buffer, result); fclose (fp); } #else result = __get_nprocs (); #endif return result; }
/* Prepare to begin reading and/or writing mount table entries from the beginning of FILE. MODE is as for `fopen'. */ FILE * __setmntent (const char *file, const char *mode) { /* Extend the mode parameter with "c" to disable cancellation in the I/O functions and "e" to set FD_CLOEXEC. */ size_t modelen = strlen (mode); char newmode[modelen + 3]; memcpy (mempcpy (newmode, mode, modelen), "ce", 3); FILE *result = fopen (file, newmode); if (result != NULL) /* We do the locking ourselves. */ __fsetlocking (result, FSETLOCKING_BYCALLER); return result; }