Пример #1
0
int main(int argc, char *argv[])
{
  void *lowest_segments[2] = { NULL, NULL };
  Elf32_Ehdr hdr;
  Elf32_Phdr *phdr;
  FILE *fi;
  maps_range maps[16];
  int map_cnt;
  int i, ret, envc, sfp;
  long *stack_frame;
  struct stat st;
  char buf[64];
  long lret;

  if (argc < 2) {
    fprintf(stderr, "usage: %s <program> [args]\n", argv[0]);
    return 1;
  }

  g_argv = argv;

  lret = g_personality(-1);
  if (g_syscall_error(lret) != -1) {
    lret |= 0x0240000; // ADDR_COMPAT_LAYOUT | ADDR_NO_RANDOMIZE
    g_personality(lret);
  }

  fi = fopen("/proc/self/maps", "r");
  CHECK_NE(fi, NULL, "fopen maps");

  for (i = 0; i < ARRAY_SIZE(maps); i++) {
    ret = fscanf(fi, "%lx-%lx %*s %*s %*s %*s %*s\n", &maps[i].start, &maps[i].end);
    if (ret <= 0)
      break;
    CHECK_EQ(ret, 2, "maps parse error");
  }
  fclose(fi);
  map_cnt = i;
  CHECK_NE(map_cnt, 0, "no maps");
  CHECK_NE(map_cnt, ARRAY_SIZE(maps), "too many maps");

  fi = fopen(argv[1], "rb");
  if (fi == NULL)
    FAIL_PERROR("fopen");

  if (fread(&hdr, 1, sizeof(hdr), fi) != sizeof(hdr))
    FAIL_PERROR("too small or");

  if (memcmp(hdr.e_ident, ELFMAG "\x01\x01", SELFMAG + 2) != 0) {
    fprintf(stderr, "not 32bit LE ELF?\n");
    return 1;
  }

  HDR_CHECK_EQ(e_type, ET_EXEC, "not executable");
  HDR_CHECK_EQ(e_machine, EM_ARM, "not ARM");
  HDR_CHECK_EQ(e_phentsize, sizeof(Elf32_Phdr), "bad PH entry size");
  HDR_CHECK_NE(e_phnum, 0, "no PH entries");

  phdr = malloc(hdr.e_phnum * hdr.e_phentsize);
  CHECK_NE(phdr, NULL, "OOM");

  if (fread(phdr, hdr.e_phentsize, hdr.e_phnum, fi) != hdr.e_phnum)
    FAIL_PERROR("too small or");

  for (i = 0; i < hdr.e_phnum; i++) {
    Elf32_Addr end_addr = phdr[i].p_vaddr + phdr[i].p_memsz;
    Elf32_Addr align;
    void *ptr, *map_ptr;

    if (phdr[i].p_type == PT_NOTE)
      continue;
    if (phdr[i].p_type != PT_LOAD) {
      fprintf(stderr, "skipping section %d\n", phdr[i].p_type);
      continue;
    }

    ret = is_range_used(maps, map_cnt, phdr[i].p_vaddr, end_addr);
    if (ret) {
      fprintf(stderr, "segment %d (%08x-%08x) hits %08lx-%08lx in maps\n",
        i, phdr[i].p_vaddr, end_addr, maps[ret - 1].start, maps[ret - 1].end);
      return 1;
    }

    log("load %d %08x-%08x from %08x\n", phdr[i].p_type,
      phdr[i].p_vaddr, end_addr, phdr[i].p_offset);

    align = phdr[i].p_vaddr & 0xfff;
    map_ptr = (void *)(phdr[i].p_vaddr - align);
    ptr = mmap(map_ptr, phdr[i].p_memsz + align, PROT_READ|PROT_WRITE|PROT_EXEC,
      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    if (ptr == MAP_FAILED || ptr != map_ptr)
      FAIL_PERROR("mmap");

    if (phdr[i].p_filesz > 0) {
      if (fseek(fi, phdr[i].p_offset, SEEK_SET) != 0)
        FAIL_PERROR("fseek");
      if (fread((char *)ptr + align, 1, phdr[i].p_filesz, fi) != phdr[i].p_filesz)
        FAIL_PERROR("too small or");

      if (phdr[i].p_flags & PF_X)
        do_patches((char *)ptr + align, phdr[i].p_filesz);
    }

    if (lowest_segments[0] == NULL || map_ptr < lowest_segments[0])
      lowest_segments[0] = map_ptr;
  }

  // build self bin path
  snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(fi));
  if (lstat(buf, &st) != 0)
    FAIL_PERROR("lstat bin_path");
  bin_path = malloc(st.st_size + 1);
  CHECK_NE(bin_path, NULL, "bin_path");
  ret = readlink(buf, bin_path, st.st_size);
  if (ret < 0)
    FAIL_PERROR("readlink");
  bin_path[ret] = 0;

  fclose(fi);

  emu_init(lowest_segments, 0);

  // generate stack frame: argc, argv[], NULL, env[], NULL
  for (envc = 0; environ[envc] != NULL; envc++)
    ;

  stack_frame = calloc(argc + envc + 3, sizeof(stack_frame[0]));
  if (stack_frame == NULL) {
    fprintf(stderr, "stack_frame OOM\n");
    return 1;
  }

  // update the environment
  setenv("_", bin_path, 1);

  sfp = 0;
  stack_frame[sfp++] = argc - 1;
  for (i = 1; i < argc; i++)
    stack_frame[sfp++] = (long)argv[i];
  stack_frame[sfp++] = 0;
  for (i = 0; i < envc; i++)
    stack_frame[sfp++] = (long)environ[i];
  stack_frame[sfp++] = 0;

  log("entering %08x, %d stack entries\n", hdr.e_entry, sfp);
  do_entry(hdr.e_entry, stack_frame, sfp, NULL);

  fprintf(stderr, "do_entry failed!\n");
  return 1;
}
Пример #2
0
int
main(int argc, char **argv)
{
	struct conf_entry *p, *q, *x, *y;
	struct pidinfo *pidlist, *pl;
	int status, listlen;
	char **av;
	
	parse_args(argc, argv);
	argc -= optind;
	argv += optind;

	if (needroot && getuid() && geteuid())
		errx(1, "You must be root.");

	p = parse_file(&listlen);
	if (argc > 0) {
		/* Only rotate specified files. */
		x = y = NULL;
		listlen = 0;
		for (av = argv; *av; av++) {
			for (q = p; q; q = q->next)
				if (strcmp(*av, q->log) == 0) {
					if (x == NULL)
						x = y = q;
					else {
						y->next = q;
						y = q;
					}
					listlen++;
					break;
				}
			if (q == NULL)
				warnx("%s: %s not found", conf, *av);
		}
		if (x == NULL)
			errx(1, "%s: no specified log files", conf);
		y->next = NULL;
		p = x;
	}

	pidlist = (struct pidinfo *)calloc(listlen + 1, sizeof(struct pidinfo));
	if (pidlist == NULL)
		err(1, "calloc");

	signal(SIGCHLD, child_killer);

	/* Step 1, rotate all log files */
	for (q = p; q; q = q->next)
		do_entry(q);

	/* Step 2, make a list of unique pid files */
	for (q = p, pl = pidlist; q; ) {
		if (q->flags & CE_ROTATED) {
			struct pidinfo *pltmp;

			for (pltmp = pidlist; pltmp < pl; pltmp++) {
				if ((q->pidfile && pltmp->file &&
				    strcmp(pltmp->file, q->pidfile) == 0 &&
				    pltmp->signal == q->signal) ||
				    (q->runcmd && pltmp->file &&
				    strcmp(q->runcmd, pltmp->file) == 0))
					break;
			}
			if (pltmp == pl) {	/* unique entry */
				if (q->runcmd) {
					pl->file = q->runcmd;
					pl->signal = -1;
				} else {
					pl->file = q->pidfile;
					pl->signal = q->signal;
				}
				pl++;
			}
		}
		q = q->next;
	}

	/* Step 3, send a signal or run a command */
	for (pl--; pl >= pidlist; pl--) {
		if (pl->file != NULL) {
			if (pl->signal == -1)
				run_command(pl->file);
			else
				send_signal(pl->file, pl->signal);
		}
	}
	if (!noaction)
		sleep(5);

	/* Step 4, compress the log.0 file if configured to do so and free */
	while (p) {
		if ((p->flags & CE_COMPACT) && (p->flags & CE_ROTATED) &&
		    p->numlogs > 0)
			compress_log(p);
		q = p;
		p = p->next;
		free(q);
	}

	/* Wait for children to finish, then exit */
	while (waitpid(-1, &status, 0) != -1)
		;
	exit(0);
}
Пример #3
0
void compile()
{
char		line[1024];
int		token_type;
USE_ITEM	*ptr;
int		old_use_count;

	token_type = get_token();

	if (token_type != NAMES)
	    err_abort("File does not start with terminal names in column one");
	
	while (token_type != EOF)
	    token_type = do_entry(NULL);

	DEBUG0(2, "Starting handling of forward USE's\n");

	for (part2=0; part2<2; part2++) {
	    old_use_count = -1;
	    DEBUG(2, "\n\nPART %d\n\n", part2);
	    while (use_list.head != NULL  &&  old_use_count != use_count) {
		old_use_count = use_count;
		for (ptr = use_list.tail; ptr != NULL; ptr = ptr->bptr) {
		    fseek(stdin, ptr->offset, 0);
		    reset_input();
		    if ((token_type = get_token()) != NAMES)
			syserr_abort("Token after a seek not NAMES");
		    (void) do_entry(ptr);
		    if (complete)
			dequeue(ptr);
		}

		for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
		    fseek(stdin, ptr->offset, 0);
		    reset_input();
		    if ((token_type = get_token()) != NAMES)
			syserr_abort("Token after a seek not NAMES");
		    (void) do_entry(ptr);
		    if (complete)
			dequeue(ptr);
		}
		
		DEBUG0(2, "Finished a pass through enqueued forward USE's\n");
	    }
	}

	if (use_list.head != NULL) {
	    fprintf(stderr, "\nError in following up use-links.  Either there is\n");
	    fprintf(stderr, "a loop in the links or they reference non-existant\n");
	    fprintf(stderr, "terminals.  The following is a list of the entries\n");
	    fprintf(stderr, "involved:\n\n");

	    for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
		fseek(stdin, ptr->offset, 0);
		fgets(line, 1024, stdin);
		fprintf(stderr, "%s", line);
	    }

	    exit(1);
	}
}