/* * Get a group entry by name and allocate space for it. */ struct group * sudo_getgrnam(const char *name) { struct cache_item key, *item; struct rbnode *node; size_t len; key.k.name = (char *) name; if ((node = rbfind(grcache_byname, &key)) != NULL) { item = (struct cache_item *) node->data; goto done; } /* * Cache group db entry if it exists or a negative response if not. */ if ((key.d.gr = getgrnam(name)) != NULL) { item = make_gritem(key.d.gr, name); if (rbinsert(grcache_byname, item) != NULL) errorx(1, "unable to cache group %s, already exists", name); } else { len = strlen(name) + 1; item = emalloc(sizeof(*item) + len); item->refcnt = 1; item->k.name = (char *) item + sizeof(*item); memcpy(item->k.name, name, len); item->d.gr = NULL; if (rbinsert(grcache_byname, item) != NULL) errorx(1, "unable to cache group %s, already exists", name); } done: item->refcnt++; return item->d.gr; }
/* * Get a group entry by gid and allocate space for it. */ struct group * sudo_getgrgid(gid_t gid) { struct cache_item key, *item; struct rbnode *node; key.k.gid = gid; if ((node = rbfind(grcache_bygid, &key)) != NULL) { item = (struct cache_item *) node->data; goto done; } /* * Cache group db entry if it exists or a negative response if not. */ if ((key.d.gr = getgrgid(gid)) != NULL) { item = make_gritem(key.d.gr, NULL); if (rbinsert(grcache_bygid, item) != NULL) errorx(1, "unable to cache gid %u (%s), already exists", (unsigned int) gid, key.d.gr->gr_name); } else { item = emalloc(sizeof(*item)); item->refcnt = 1; item->k.gid = gid; item->d.gr = NULL; if (rbinsert(grcache_bygid, item) != NULL) errorx(1, "unable to cache gid %u, already exists", (unsigned int) gid); } done: item->refcnt++; return item->d.gr; }
void improvesolution(allinfo *a, state *v) { if (v->wsum > a->c) errorx("wrong improvesoluton"); if (v->psum <= a->z) errorx("not improved solution"); a->z = v->psum; a->zwsum = v->wsum; a->ovect = v->vect; memcpy(a->ovitem, a->vitem, sizeof(item *) * MAXV); }
void pop(allinfo *a, int side, item **f, item **l) { interval *pos; switch (side) { case LEFT : if (a->intv1 == a->intv1b) errorx("pop left"); (a->intv1)--; pos = a->intv1; break; case RIGHT: if (a->intv2 == a->intv2b) errorx("pop right"); (a->intv2)++; pos = a->intv2; break; } *f = pos->f; *l = pos->l; }
/* * emalloc() calls the system malloc(3) and exits with an error if * malloc(3) fails. */ void * emalloc(size_t size) { void *ptr; if (size == 0) errorx(1, _("internal error, tried to emalloc(0)")); if ((ptr = malloc(size)) == NULL) errorx(1, _("unable to allocate memory")); return ptr; }
/* * erealloc() calls the system realloc(3) and exits with an error if * realloc(3) fails. You can call erealloc() with a NULL pointer even * if the system realloc(3) does not support this. */ void * erealloc(void *ptr, size_t size) { if (size == 0) errorx(1, _("internal error, tried to erealloc(0)")); ptr = ptr ? realloc(ptr, size) : malloc(size); if (ptr == NULL) errorx(1, _("unable to allocate memory")); return ptr; }
/* * emalloc2() allocates nmemb * size bytes and exits with an error * if overflow would occur or if the system malloc(3) fails. */ void * emalloc2(size_t nmemb, size_t size) { void *ptr; if (nmemb == 0 || size == 0) errorx(1, _("internal error, tried to emalloc2(0)")); if (nmemb > SIZE_MAX / size) errorx(1, _("internal error, emalloc2() overflow")); size *= nmemb; if ((ptr = malloc(size)) == NULL) errorx(1, _("unable to allocate memory")); return ptr; }
/* * erealloc3() realloc(3)s nmemb * size bytes and exits with an error * if overflow would occur or if the system malloc(3)/realloc(3) fails. * You can call erealloc() with a NULL pointer even if the system realloc(3) * does not support this. */ void * erealloc3(void *ptr, size_t nmemb, size_t size) { if (nmemb == 0 || size == 0) errorx(1, _("internal error, tried to erealloc3(0)")); if (nmemb > SIZE_MAX / size) errorx(1, _("internal error, erealloc3() overflow")); size *= nmemb; ptr = ptr ? realloc(ptr, size) : malloc(size); if (ptr == NULL) errorx(1, _("unable to allocate memory")); return ptr; }
/** * vcpu_enable_paged_mode() - enabled paged mode on a virtual CPU * * @vm: virtual machine descriptor * @vcpu: ID of a virtual CPU to enable paged mode on * @pdir: guest physical address for an identity page directory * * Return: zero on success, or -1 if an error occurred */ int vcpu_enable_paged_mode(struct vm *vm, unsigned vcpu, uintptr_t pdir) { struct kvm_sregs sregs; uint32_t *pd; int i; if (vcpu_get_sregs(vm, vcpu, &sregs) == 0) { sregs.cr0 |= CR0_PG; sregs.cr4 |= CR4_PSE; sregs.cr3 = pdir; pd = vm_get_memory(vm, pdir, PAGE_SIZE); if (pd != NULL) { /* Initialize identity mapping */ for (i = 0; i < 1024; i++) pd[i] = (i << 22) | PDE_PS | PDE_S | PDE_RWP; if (vcpu_set_sregs(vm, vcpu, &sregs) == 0) return 0; } } errorx("failed to enable paging mode on VCPU #%u", vcpu); return -1; }
int linux_audit_command(char *argv[], int result) { int au_fd, rc; char *command, *cp, **av; size_t size, n; if ((au_fd = linux_audit_open()) == -1) return -1; /* Convert argv to a flat string. */ for (size = 0, av = argv; *av != NULL; av++) size += strlen(*av) + 1; command = cp = emalloc(size); for (av = argv; *av != NULL; av++) { n = strlcpy(cp, *av, size - (cp - command)); if (n >= size - (cp - command)) errorx(1, "internal error, linux_audit_command() overflow"); cp += n; *cp++ = ' '; } *--cp = '\0'; /* Log command, ignoring ECONNREFUSED on error. */ rc = audit_log_user_command(au_fd, AUDIT_USER_CMD, command, NULL, result); if (rc <= 0 && errno != ECONNREFUSED) warning("unable to send audit message"); efree(command); return rc; }
/* * evasprintf() calls vasprintf() and exits with an error if vasprintf() * returns -1 (out of memory). */ int evasprintf(char **ret, const char *format, va_list args) { int len; if ((len = vasprintf(ret, format, args)) == -1) errorx(1, _("unable to allocate memory")); return len; }
void push(allinfo *a, int side, item *f, item *l) { interval *pos; switch (side) { case LEFT : pos = a->intv1; (a->intv1)++; break; case RIGHT: pos = a->intv2; (a->intv2)--; break; } if (a->intv1 == a->intv2) errorx("interval stack full"); pos->f = f; pos->l = l; }
static int match_expr(struct search_node *head, struct log_info *log) { struct search_node *sn; int matched = 1, rc; for (sn = head; sn; sn = sn->next) { /* If we have no match, skip ahead to the next OR entry. */ if (!matched && !sn->or) continue; switch (sn->type) { case ST_EXPR: matched = match_expr(sn->u.expr, log); break; case ST_CWD: matched = strcmp(sn->u.cwd, log->cwd) == 0; break; case ST_TTY: matched = strcmp(sn->u.tty, log->tty) == 0; break; case ST_RUNASGROUP: matched = strcmp(sn->u.runas_group, log->runas_group) == 0; break; case ST_RUNASUSER: matched = strcmp(sn->u.runas_user, log->runas_user) == 0; break; case ST_USER: matched = strcmp(sn->u.user, log->user) == 0; break; case ST_PATTERN: #ifdef HAVE_REGCOMP rc = regexec(&sn->u.cmdre, log->cmd, 0, NULL, 0); if (rc && rc != REG_NOMATCH) { char buf[BUFSIZ]; regerror(rc, &sn->u.cmdre, buf, sizeof(buf)); errorx(1, "%s", buf); } matched = rc == REG_NOMATCH ? 0 : 1; #else matched = strstr(log.cmd, sn->u.pattern) != NULL; #endif break; case ST_FROMDATE: matched = log->tstamp >= sn->u.tstamp; break; case ST_TODATE: matched = log->tstamp <= sn->u.tstamp; break; } if (sn->negated) matched = !matched; } return matched; }
/* * Similar to putenv(3) but operates on sudo's private copy of the * environment (not environ) and it always overwrites. The dupcheck param * determines whether we need to verify that the variable is not already set. * Will only overwrite an existing variable if overwrite is set. */ static void sudo_putenv(char *str, int dupcheck, int overwrite) { char **ep; size_t len; int found = FALSE; /* Make sure there is room for the new entry plus a NULL. */ if (env.env_len + 2 > env.env_size) { env.env_size += 128; env.envp = erealloc3(env.envp, env.env_size, sizeof(char *)); #ifdef ENV_DEBUG memset(env.envp + env.env_len, 0, (env.env_size - env.env_len) * sizeof(char *)); #endif } #ifdef ENV_DEBUG if (env.envp[env.env_len] != NULL) errorx(1, _("sudo_putenv: corrupted envp, length mismatch")); #endif if (dupcheck) { len = (strchr(str, '=') - str) + 1; for (ep = env.envp; !found && *ep != NULL; ep++) { if (strncmp(str, *ep, len) == 0) { if (overwrite) *ep = str; found = TRUE; } } /* Prune out duplicate variables. */ if (found && overwrite) { while (*ep != NULL) { if (strncmp(str, *ep, len) == 0) { char **cur = ep; while ((*cur = *(cur + 1)) != NULL) cur++; } else { ep++; } } env.env_len = ep - env.envp; } } if (!found) { ep = env.envp + env.env_len; env.env_len++; *ep++ = str; *ep = NULL; } }
int main(int argc, char *argv[]) { const char *zipfile; int nopts; if (isatty(STDOUT_FILENO)) tty = 1; if (getenv("UNZIP_DEBUG") != NULL) unzip_debug = 1; for (int i = 0; i < argc; ++i) debug("%s%c", argv[i], (i < argc - 1) ? ' ' : '\n'); /* * Info-ZIP's unzip(1) expects certain options to come before the * zipfile name, and others to come after - though it does not * enforce this. For simplicity, we accept *all* options both * before and after the zipfile name. */ nopts = getopts(argc, argv); /* * When more of the zipinfo mode options are implemented, this * will need to change. */ if (zipinfo_mode && !Z1_opt) { printf("Zipinfo mode needs additional options\n"); exit(1); } if (argc <= nopts) usage(); zipfile = argv[nopts++]; if (strcmp(zipfile, "-") == 0) zipfile = NULL; /* STDIN */ while (nopts < argc && *argv[nopts] != '-') add_pattern(&include, argv[nopts++]); nopts--; /* fake argv[0] */ nopts += getopts(argc - nopts, argv + nopts); if (n_opt + o_opt + u_opt > 1) errorx("-n, -o and -u are contradictory"); time(&now); unzip(zipfile); exit(0); }
/* * Get a password entry by name and allocate space for it. */ struct passwd * sudo_getpwnam(const char *name) { struct cache_item key, *item; struct rbnode *node; size_t len; debug_decl(sudo_getpwnam, SUDO_DEBUG_NSS) key.k.name = (char *) name; if ((node = rbfind(pwcache_byname, &key)) != NULL) { item = (struct cache_item *) node->data; goto done; } /* * Cache passwd db entry if it exists or a negative response if not. */ #ifdef HAVE_SETAUTHDB aix_setauthdb((char *) name); #endif if ((key.d.pw = getpwnam(name)) != NULL) { item = make_pwitem(key.d.pw, name); if (rbinsert(pwcache_byname, item) != NULL) errorx(1, _("unable to cache user %s, already exists"), name); } else { len = strlen(name) + 1; item = ecalloc(1, sizeof(*item) + len); item->refcnt = 1; item->k.name = (char *) item + sizeof(*item); memcpy(item->k.name, name, len); /* item->d.pw = NULL; */ if (rbinsert(pwcache_byname, item) != NULL) errorx(1, _("unable to cache user %s, already exists"), name); } #ifdef HAVE_SETAUTHDB aix_restoreauthdb(); #endif done: item->refcnt++; debug_return_ptr(item->d.pw); }
/* * Get a password entry by uid and allocate space for it. */ struct passwd * sudo_getpwuid(uid_t uid) { struct cache_item key, *item; struct rbnode *node; debug_decl(sudo_getpwuid, SUDO_DEBUG_NSS) key.k.uid = uid; if ((node = rbfind(pwcache_byuid, &key)) != NULL) { item = (struct cache_item *) node->data; goto done; } /* * Cache passwd db entry if it exists or a negative response if not. */ #ifdef HAVE_SETAUTHDB aix_setauthdb(IDtouser(uid)); #endif if ((key.d.pw = getpwuid(uid)) != NULL) { item = make_pwitem(key.d.pw, NULL); if (rbinsert(pwcache_byuid, item) != NULL) errorx(1, _("unable to cache uid %u (%s), already exists"), (unsigned int) uid, item->d.pw->pw_name); } else { item = ecalloc(1, sizeof(*item)); item->refcnt = 1; item->k.uid = uid; /* item->d.pw = NULL; */ if (rbinsert(pwcache_byuid, item) != NULL) errorx(1, _("unable to cache uid %u, already exists"), (unsigned int) uid); } #ifdef HAVE_SETAUTHDB aix_restoreauthdb(); #endif done: item->refcnt++; debug_return_ptr(item->d.pw); }
/* * easprintf() calls vasprintf() and exits with an error if vasprintf() * returns -1 (out of memory). */ int easprintf(char **ret, const char *fmt, ...) { int len; va_list ap; va_start(ap, fmt); len = vasprintf(ret, fmt, ap); va_end(ap); if (len == -1) errorx(1, _("unable to allocate memory")); return len; }
void partsort(allinfo *a, item *f, item *l, stype ws, int what) { register ptype mp, mw; register item *i, *j, *m; register stype wi; register int d; d = l - f + 1; if (d < 1) errorx("negative interval in partsort"); if (d > MINMED) { m = median(f, l, (int) sqrt((double)d)); } else { if (d > 1) { m = f + d / 2; if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); if (d > 2) { if (DET(m->p, m->w, l->p, l->w) < 0) { SWAP(m, l); if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); } } } } if (d > 3) { mp = m->p; mw = m->w; i = f; j = l; wi = ws; for (;;) { do { wi += i->w; i++; } while (DET(i->p, i->w, mp, mw) > 0); do { j--; } while (DET(j->p, j->w, mp, mw) < 0); if (i > j) break; SWAP(i, j); } if (wi <= a->cstar) { if (what == SORTALL) partsort(a, f, i-1, ws, what); if (what == PARTIATE) push(a, LEFT, f, i-1); partsort(a, i, l, wi, what); } else { if (what == SORTALL) partsort(a, i, l, wi, what); if (what == PARTIATE) push(a, RIGHT, i, l); partsort(a, f, i-1, ws, what); } } if ((d <= 3) || (what == SORTALL)) { a->fpart = f; a->lpart = l; a->wfpart = ws; } }
void multiply(allinfo *a, item *h, int side) { register state *i, *j, *k, *m; register itype p, w; register btype mask0, mask1; state *r1, *rm; if (a->d.size == 0) return; if (side == RIGHT) { p = h->p; w = h->w; } else { p = -h->p; w = -h->w; } if (2*a->d.size + 2 > MAXSTATES) errorx("no space in multiply"); /* keep track on solution vector */ a->vno++; if (a->vno == MAXV) a->vno = 0; mask1 = ((btype) 1 << a->vno); mask0 = ~mask1; a->vitem[a->vno] = h; /* initialize limits */ r1 = a->d.fset; rm = a->d.lset; k = a->d.set1; m = rm + 1; k->psum = -1; k->wsum = r1->wsum + abs(p) + 1; m->wsum = rm->wsum + abs(w) + 1; for (i = r1, j = r1; (i != m) || (j != m); ) { if (i->wsum <= j->wsum + w) { if (i->psum > k->psum) { if (i->wsum > k->wsum) k++; k->psum = i->psum; k->wsum = i->wsum; k->vect = i->vect & mask0; } i++; } else { if (j->psum + p > k->psum) { if (j->wsum + w > k->wsum) k++; k->psum = j->psum + p; k->wsum = j->wsum + w; k->vect = j->vect | mask1; } j++; } } a->d.fset = a->d.set1; a->d.lset = k; a->d.size = a->d.lset - a->d.fset + 1; a->coresize++; if (a->d.size > a->maxstates) a->maxstates = a->d.size; }
static int sched_use_signal(const int sig) { struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; /* Restart functions if interrupted by handler */ if (sigaction(sig, &sa, NULL) == -1) { errorx("sigaction"); return 1; } return 0; }
int main(int argc, char *argv[]) { size_t len; FILE *fp; char *cp, *dash, *line, lines[2][2048]; int which = 0; if (argc != 2) usage(); fp = fopen(argv[1], "r"); if (fp == NULL) errorx(1, "unable to open %s", argv[1]); /* * Each test record consists of a log entry on one line and a list of * line lengths to test it with on the next. E.g. * * Jun 30 14:49:51 : millert : TTY=ttypn ; PWD=/usr/src/local/millert/hg/sudo/trunk/plugins/sudoers ; USER=root ; TSID=0004LD ; COMMAND=/usr/local/sbin/visudo * 60-80,40 */ while ((line = fgets(lines[which], sizeof(lines[which]), fp)) != NULL) { len = strcspn(line, "\n"); line[len] = '\0'; /* If we read the 2nd line, parse list of line lengths and check. */ if (which) { for (cp = strtok(lines[1], ","); cp != NULL; cp = strtok(NULL, ",")) { size_t maxlen; /* May be either a number or a range. */ len = maxlen = atoi(cp); dash = strchr(cp, '-'); if (dash) maxlen = atoi(dash + 1); while (len <= maxlen) { printf("# word wrap at %d characters\n", (int)len); writeln_wrap(stdout, lines[0], strlen(lines[0]), len); len++; } } } which = !which; } exit(0); }
/** * vcpu_init() - perform common initialization of a virtual CPU * * @vm: virtual machine descriptor * @vcpu: ID of a virtual CPU to initialize * @entry: guest physical entry point (RIP value) * @stack: guest physical stack top (RSP value) * * Return: zero on success, or -1 if an error occurred */ int vcpu_init(struct vm *vm, unsigned vcpu, uintptr_t entry, uintptr_t stack) { struct kvm_regs regs; if (vcpu_get_regs(vm, vcpu, ®s) == 0) { regs.rflags = 0x2; regs.rip = entry; regs.rsp = stack; if (vcpu_set_regs(vm, vcpu, ®s) == 0) return 0; } errorx("failed to initiazle VCPU #%u", vcpu); return -1; }
state *findvect(stype ws, state *f, state *l) { /* find vector i, so that i->wsum <= ws < (i+1)->wsum */ register state *m; /* a set should always have at least one vector */ if (f > l) errorx("findvect: empty set"); if (f->wsum > ws) return NULL; if (l->wsum <= ws) return l; while (l - f > SYNC) { m = f + (l - f) / 2; if (m->wsum > ws) { l = m-1; } else { f = m; } } while (l->wsum > ws) l--; return l; }
/* * Similar to setenv(3) but operates on sudo's private copy of the environment * (not environ) and it always overwrites. The dupcheck param determines * whether we need to verify that the variable is not already set. */ static void sudo_setenv(const char *var, const char *val, int dupcheck) { char *estring; size_t esize; esize = strlen(var) + 1 + strlen(val) + 1; estring = emalloc(esize); /* Build environment string and insert it. */ if (strlcpy(estring, var, esize) >= esize || strlcat(estring, "=", esize) >= esize || strlcat(estring, val, esize) >= esize) { errorx(1, _("internal error, sudo_setenv() overflow")); } sudo_putenv(estring, dupcheck, TRUE); }
static ssize_t read_nonblock(int fd, char *buf, size_t size) { ssize_t nr; nr = read(fd, buf, size); if (nr == -1) { if (errno == EAGAIN) { /* no more reading */ return 0; } errorx("read from %d", fd); return -1; } /* Note read(2) returns 0 for end-of-pipe */ return nr; }
/** * vcpu_enable_protected_mode() - enable protected mode on a virtual CPU * * @vm: virtual machine descriptor * @vcpu: ID of a virtual CPU to enable protected mode on * * Return: zero on success, or -1 if an error occurred */ int vcpu_enable_protected_mode(struct vm *vm, unsigned vcpu) { struct kvm_sregs sregs; if (vcpu_get_sregs(vm, vcpu, &sregs) == 0) { sregs.cs.base = sregs.ss.base = sregs.ds.base = 0x0; sregs.cs.limit = sregs.ss.limit = sregs.ds.limit = 0xffffffff; sregs.cs.g = sregs.ss.g = sregs.ds.g = 1; sregs.cs.db = sregs.ss.db = 1; sregs.cr0 |= CR0_PE; if (vcpu_set_sregs(vm, vcpu, &sregs) == 0) return 0; } errorx("failed to enable protected mode on VCPU #%u", vcpu); return -1; }
int main(int argc, char *argv[]) { const char *zipfile; int nopts; if (isatty(STDOUT_FILENO)) tty = 1; if (getenv("UNZIP_DEBUG") != NULL) unzip_debug = 1; for (int i = 0; i < argc; ++i) debug("%s%c", argv[i], (i < argc - 1) ? ' ' : '\n'); /* * Info-ZIP's unzip(1) expects certain options to come before the * zipfile name, and others to come after - though it does not * enforce this. For simplicity, we accept *all* options both * before and after the zipfile name. */ nopts = getopts(argc, argv); if (argc <= nopts) usage(); zipfile = argv[nopts++]; while (nopts < argc && *argv[nopts] != '-') add_pattern(&include, argv[nopts++]); nopts--; /* fake argv[0] */ nopts += getopts(argc - nopts, argv + nopts); if (n_opt + o_opt + u_opt > 1) errorx("-n, -o and -u are contradictory"); time(&now); unzip(zipfile); exit(0); }
static int dofort(char *s) { int nparms, i; char *params[MAXARGS]; nparms = 0; ADD(FCOM); for (i = 0; i < ffmax; i++) ADD(ffary[i]); ADD(s); ADD(asmfname); ADD(NULL); infname = s; if (callsys(fcom, params)) errorx("Error. No assembly."); doasm(s); if (saveasmflag == NO) rmf(asmfname); return(0); }
struct status_line * ini_load_status_line(const char *inifile) { static const char * const system = SYSCONFDIR "/i3blocks.conf"; const char * const home = getenv("HOME"); char buf[PATH_MAX]; FILE *fp; struct status_line *status; struct status_line *parse(void) { status = calloc(1, sizeof(struct status_line)); if (status && parse_status_line(fp, status)) { free(status->blocks); free(status->updated_blocks); free(status); status = NULL; } if (fclose(fp)) errorx("fclose"); return status; }