Пример #1
0
int steal_cleanup_child(struct steal_pty_state *steal) {
    if (ptrace_memcpy_to_child(&steal->child,
                               steal->child_scratch,
                               "/dev/null", sizeof("/dev/null"))) {
        return steal->child.error;
    }

    int nullfd = do_syscall(&steal->child, openat, -1, steal->child_scratch, O_RDWR, 0, 0, 0);
    if (nullfd < 0) {
        return steal->child.error;
    }

    int i;
    for (i = 0; i < steal->master_fds.n; ++i) {
        do_dup2(&steal->child, nullfd, steal->master_fds.fds[i]);
    }

    do_syscall(&steal->child, close, nullfd, 0, 0, 0, 0, 0);
    do_syscall(&steal->child, close, steal->child_fd, 0, 0, 0, 0, 0);

    steal->child_fd = 0;

    ptrace_restore_regs(&steal->child);

    ptrace_detach_child(&steal->child);
    ptrace_wait(&steal->child);
    return 0;
}
Пример #2
0
static int do_fork(struct ptrace_child *child) {
    if (ptrace_syscall_numbers(child)->nr_fork != -1) {
        return do_syscall(child, fork, 0, 0, 0, 0, 0, 0);
    } else {
        return do_syscall(child, clone, SIGCHLD, 0, 0, 0, 0, 0);
    }
}
Пример #3
0
static int do_dup2(struct ptrace_child *child, int oldfd, int newfd) {
    if (oldfd == newfd) {
        return 0;
    }
    if (ptrace_syscall_numbers(child)->nr_dup2 != -1) {
        return do_syscall(child, dup2, oldfd, newfd, 0, 0, 0, 0);
    } else {
        return do_syscall(child, dup3, oldfd, newfd, 0, 0, 0, 0);
    }
}
Пример #4
0
int do_setsid(struct ptrace_child *child) {
    int err = 0;
    struct ptrace_child dummy;

    err = do_fork(child);
    if (err < 0)
        return err;

    debug("Forked a child: %ld", child->forked_pid);

    err = ptrace_finish_attach(&dummy, child->forked_pid);
    if (err < 0)
        goto out_kill;

    dummy.state = ptrace_after_syscall;
    copy_user(&dummy, child);
    if (ptrace_restore_regs(&dummy)) {
        err = dummy.error;
        goto out_kill;
    }

    err = do_syscall(&dummy, setpgid, 0, 0, 0, 0, 0, 0);
    if (err < 0) {
        error("Failed to setpgid: %s", strerror(-err));
        goto out_kill;
    }

    move_process_group(child, child->pid, dummy.pid);

    err = do_syscall(child, setsid, 0, 0, 0, 0, 0, 0);
    if (err < 0) {
        error("Failed to setsid: %s", strerror(-err));
        move_process_group(child, dummy.pid, child->pid);
        goto out_kill;
    }

    debug("Did setsid()");

out_kill:
    kill(dummy.pid, SIGKILL);
    ptrace_wait(&dummy);
    ptrace_detach_child(&dummy);
    do_syscall(child, wait4, dummy.pid, 0, WNOHANG, 0, 0, 0);
    return err;
}
Пример #5
0
int _stat (const char *fname, struct stat *st)
{
  int block[2];

  block[0] = (int) fname;
  block[1] = (int) st;

  return do_syscall (SYS_stat, block);
}
Пример #6
0
/** \brief  Wait on a condition variable until another thread either signals
  *         or broadcasts.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function will cause the callling thread to wait on the condition
  * variable. The thread can be woken up by either signalling or broadcasting
  * to the condition variable. The mutex object parameter is unlocked if the 
  * thread will be blocked because of this function and will be relocked
  * before the function returns to the caller.
  *
  * \param cond     This parameter is the condition variable object which will
  *                 be used. This parameter should be a pointer to a valid
  *                 memory location.
  * \param mutex    This parameter is the mutex object which will be used. The
  *                 parameter should be a pointer to a valid memory location.
  * \return         The return value is one of the following:
  *                 - HTHREAD_SUCCESS\n
  *                     The function successfully processed the request.
  *                 - HTHREAD_FAILURE\n
  *                     The function failed to process the request.
  */
Hint hthread_cond_wait( hthread_cond_t *cond, hthread_mutex_t *mutex )
{
    return (Hint)do_syscall( HTHREAD_SYSCALL_COND_WAIT,
                             (void*)cond,
                             (void*)mutex,
                             NULL,
                             NULL,
                             NULL );
}
Пример #7
0
/** \brief  Signal a condition variable object to wake up all threads which
  *         is waiting for the condition to occur.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function will wake up all of the threads which are waiting on the
  * condition variable. If the condition variable has no waiting threads
  * then nothing will occur.
  *
  * \param cond     This parameter is the condition variable object which will
  *                 be used. This parameter should be a pointer to a valid
  *                 memory location.
  * \return         The return value is one of the following:
  *                 - HTHREAD_SUCCESS\n
  *                     The function successfully processed the request.
  *                 - HTHREAD_FAILURE\n
  *                     The function failed to process the request.
  */
Hint hthread_cond_broadcast( hthread_cond_t *cond )
{
    return (Hint)do_syscall( HTHREAD_SYSCALL_COND_BROADCAST,
                             (void*)cond,
                             NULL,
                             NULL,
                             NULL,
                             NULL );
}
Пример #8
0
/** \internal
  * \brief  Set the given threads scheduling parameter.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function sets the given threads priority value and returns
  * it to the caller. The priority of a thread ranges from 0 to 127 with
  * smaller values indicating higher priorities.
  *
  * Setting a threads priority can only be done by the thread itself or
  * the parent of the thread. If a thread other than these two attempts
  * to change another thread's priority then an error value will be returned.
  *
  * \param  th  The thread id of the thread to set the priority for.
  * \param  pl  The scheduling policy to use. This parameter is unused.
  * \param  pr  The priority value to give to the thread. This value should
  *             be in the range 0 to 127 with lower values indicating higher
  *             priority.
  * \return     This function returns one of the following:\n
  *             - HT_SUCCESS\n
  *                 The thread's priority was updated to the new value.
  *             - HT_FAILURE\n
  *                 The thread's priority was not updated because the
  *                 set priority operation failed.
  */
Hint hthread_setschedparam( hthread_t th, Hint pl, const struct sched_param *pr )
{   
	return (Hint)do_syscall(    HTHREAD_SYSCALL_SETPRI,
                                (void*)th,
                                (void*)(pr->sched_priority),
                                NULL,
                                NULL,
                                NULL );
}
Пример #9
0
/** \brief  Signal a condition variable object to wake up one thread which
  *         is waiting for the condition to occur.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function will wake up a single thread which is waiting on the
  * condition variable. If the condition variable has no waiting threads
  * then nothing will occur.
  *
  * This function will wake up exactly one thread, however, the exact thread
  * which is woken up is undefined.
  *
  * \param cond     This parameter is the condition variable object which will
  *                 be used. This parameter should be a pointer to a valid
  *                 memory location.
  * \return         The return value is one of the following:
  *                 - HTHREAD_SUCCESS\n
  *                     The function successfully processed the request.
  *                 - HTHREAD_FAILURE\n
  *                     The function failed to process the request.
  */
Hint hthread_cond_signal( hthread_cond_t *cond )
{
    return (Hint)do_syscall( HTHREAD_SYSCALL_COND_SIGNAL,
                             (void*)cond,
                             NULL,
                             NULL,
                             NULL,
                             NULL );
}
Пример #10
0
/** \brief  Attempt to acquire a mutex but return an error condition if the
  *         mutex could not be acquired.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function will attempt to acquire a mutex. If the mutex is already
  * held by another thread then the function will return with a failure
  * instead of blocking until the mutex can be acquired.
  *
  * \param mutex    This parameter is the mutex object which is going to
  *                 be acquired. This parameter should be a pointer to a
  *                 valid memory location.
  * \return         The return value is one of the following:
  *                 - HTHREAD_SUCCESS\n
  *                     The mutex was successfully acquired.
  *                 - HTHREAD_BUSY\n
  *                     The mutex has already been locked by another thread. 
  *                 - HTHREAD_FAILURE\n
  *                     The lock was not acquired. This indicates that either
  *                     the mutex object is invalid or that some unknown
  *                     error has occurred.
  */
Hint hthread_mutex_trylock( hthread_mutex_t *mutex )
{
    return (Hint)do_syscall( HTHREAD_SYSCALL_MUTEX_TRYLOCK,
                             (void*)mutex,
                             NULL,
                             NULL,
                             NULL,
                             NULL );
}
Пример #11
0
int ignore_hup(struct ptrace_child *child, unsigned long scratch_page) {
    int err;
    if (ptrace_syscall_numbers(child)->nr_signal != -1) {
        err = do_syscall(child, signal, SIGHUP, (unsigned long)SIG_IGN, 0, 0, 0, 0);
    } else {
        struct sigaction act = {
            .sa_handler = SIG_IGN,
        };
        err = ptrace_memcpy_to_child(child, scratch_page,
                                     &act, sizeof act);
        if (err < 0)
            return err;
        err = do_syscall(child, rt_sigaction,
                         SIGHUP, scratch_page,
                         0, 8, 0, 0);
    }
    return err;
}
Пример #12
0
int
_kill (int n, int m)
{
  int block[2];

  block[0] = n;
  block[1] = m;

  return do_syscall (SYS_kill, block);
}
Пример #13
0
int
_open (const char *path, int flags)
{
  int block[2];

  block[0] = (int) path;
  block[1] = flags;

  return do_syscall (SYS_open, block);
}
Пример #14
0
int
_fstat (int file, struct stat *st)
{
  int block[2];

  block[0] = file;
  block[1] = (int) st;

  return do_syscall (SYS_fstat, block);
}
Пример #15
0
int
_lseek (int file, int ptr, int whence)
{
  int block[3];

  block[0] = file;
  block[1] = ptr;
  block[2] = whence;

  return do_syscall (SYS_lseek, block);
}
Пример #16
0
int
_write (int file, char *ptr, int len)
{
  int block[3];

  block[0] = file;
  block[1] = (int) ptr;
  block[2] = len;

  return do_syscall (SYS_write, block);
}
Пример #17
0
// Find the fd(s) in the terminal emulator process that corresponds to
// the master side of the target's pty. Store the result in
// steal->master_fds.
int find_master_fd(struct steal_pty_state *steal) {
    DIR *dir;
    struct dirent *d;
    struct stat st;
    int err;
    char buf[PATH_MAX];

    snprintf(buf, sizeof buf, "/proc/%d/fd/", steal->child.pid);
    if ((dir = opendir(buf)) == NULL)
        return errno;
    while ((d = readdir(dir)) != NULL) {
        if (d->d_name[0] == '.') continue;
        snprintf(buf, sizeof buf, "/proc/%d/fd/%s", steal->child.pid, d->d_name);
        if (stat(buf, &st) < 0)
            continue;

        debug("Checking fd: %s: st_dev=%x", d->d_name, (int)st.st_rdev);

        if (st.st_rdev != PTMX_DEVICE)
            continue;

        debug("found a ptmx fd: %s", d->d_name);
        err = do_syscall(&steal->child, ioctl,
                         atoi(d->d_name),
                         TIOCGPTN,
                         steal->child_scratch,
                         0, 0, 0);
        if (err < 0) {
            debug(" error doing TIOCGPTN: %s", strerror(-err));
            continue;
        }
        int ptn;
        err = ptrace_memcpy_from_child(&steal->child, &ptn,
                                       steal->child_scratch, sizeof(ptn));
        if (err < 0) {
            debug(" error getting ptn: %s", strerror(steal->child.error));
            continue;
        }
        if (ptn == (int)minor(steal->target_stat.ctty)) {
            debug("found a master fd: %d", atoi(d->d_name));
            if (fd_array_push(&steal->master_fds, atoi(d->d_name)) != 0) {
                error("unable to allocate memory for fd array!");
                return ENOMEM;
            }
        }
    }

    if (steal->master_fds.n == 0) {
        return ESRCH;
    }
    return 0;
}
Пример #18
0
/** \internal
  * \brief  Retreive the given threads priority.
  *
  * \author Wesley Peck <*****@*****.**>
  *
  * This function retrieves the given threads priority value and returns
  * it to the caller. The priority of a thread ranges from 0 to 127 with
  * smaller values indicating higher priorities.
  *
  * \param  th  The thread id to retrieve the priority of.
  * \return     This function returns a positive value in the range 0 to 127
  *             upon success and a negative value to indicate failure.
  */ 
Hint hthread_getschedparam( hthread_t th, Hint *policy, struct sched_param *pr )
{   
    // Make sure policy is not a NULL pointer before
    // dereferencing it. You may accidentally write
    // to the Microblaze's IVT
    if (policy != NULL)
        *policy = SCHED_OTHER;
	return (Hint)do_syscall(    HTHREAD_SYSCALL_GETPRI,
                                (void*)th,
                                (void*)(&pr->sched_priority),
                                NULL,
                                NULL,
                                NULL );
}
Пример #19
0
static inline int
syscall(int num, ...) {
    va_list ap;
    va_start(ap, num);
    uint32_t a[MAX_ARGS];
    int i, ret;
    for (i = 0; i < MAX_ARGS; i ++) {
        a[i] = va_arg(ap, uint32_t);
    }
    va_end(ap);

    ret = do_syscall(a[0], a[1], a[2], a[3], a[4], num);
    return ret;
}
Пример #20
0
int ignore_hup(struct ptrace_child *child, child_addr_t scratch_page) {
    int err;

    struct sigaction act = {
        .sa_handler = SIG_IGN,
    };
    err = ptrace_memcpy_to_child(child, scratch_page,
                                 &act, sizeof act);
    if (err < 0)
        return err;
    err = do_syscall(child, rt_sigaction,
                     SIGHUP, (unsigned long)scratch_page,
                     0, 8, 0, 0);

    return err;
}
Пример #21
0
static void syscall_handler(struct dune_tf *tf)
{
//	printf("Syscall No. %d\n", tf->rax);

	if (tf->rax >= SYSCALL_START)
		return do_syscall(tf, tf->rax - SYSCALL_START);

	if (syscall_check_params(tf) == -1)
		return;

	KSTATS_POP(NULL);
	KSTATS_PUSH(posix_syscall, NULL);
	syscall_do(tf);
	KSTATS_POP(NULL);
	KSTATS_PUSH(user, NULL);
}
Пример #22
0
int main( int argc, char *argv[] )
{
    char buf[65536] __attribute__((aligned(32)));
    uint32_t aica_addr = AICA_RAM_BASE;
    int len;
    int totallen = 0;

    aica_disable();
    /* Load ARM program from stdin and copy to ARM memory */
    while( (len = read(0, buf, sizeof(buf))) > 0 ) {
        if(memcpy_to_aica( aica_addr, buf, len ) != 0 ) {
            printf( "Failed to load program!\n" );
            return 1;
        }
        aica_addr += len;
        totallen += len;
    }
    printf( "Program loaded (%d bytes)\n", totallen);

    /* Main loop waiting for IO commands */
    aica_enable();
    do {
        g2_fifo_wait();
        irq_disable();
        int syscall = long_read(AICA_SYSCALL);
        irq_enable();
        if( syscall != -1 ) {
            if( syscall == -2 ) {
                fprintf( stderr, "ARM aborted with general exception\n" );
                return -2;
            } else if( syscall == SYS_EXIT ) {
                printf( "Exiting at ARM request\n" );
                aica_disable();
                return long_read(AICA_SYSCALL_ARG1);
            } else {
                uint32_t result = do_syscall( syscall, long_read(AICA_SYSCALL_ARG1),
                                              long_read(AICA_SYSCALL_ARG2), long_read(AICA_SYSCALL_ARG3) );
                g2_fifo_wait();
                irq_disable();
                long_write( AICA_SYSCALL_RETURN, result );
                long_write( AICA_SYSCALL, -1 );
                irq_enable();
            }
        }
    } while( 1 );
}
Пример #23
0
void main (int argc, char* argv[])
{
  int i;
  int rc = 0;

  /* Open the file */

  strcat(the_file, dir_name);
  strcat(the_file, "/");
  strcat(the_file, file_name);

  if ((fp = open (the_file, O_RDWR)) == -1) {
      fprintf (stderr, "error opening %s\n", the_file);
      exit (-1);
  }

  int my_pid = getpid();
  fprintf(stdout, "System call getpid() returns %d\n", my_pid);


  /* open the input file */
  if ((fdin = open (argv[1], O_RDONLY)) < 0)
      errx (-1, "can't open input for reading");
  /* find size of input file */
  if (fstat (fdin,&statbuf) < 0)
      errx (-1,"fstat error");
  /* mmap the input file */
  if ((src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == (caddr_t) -1) 
      errx (-1, "mmap error for input");

  do_syscall("vmlogger_new");
  fprintf(stdout, "Module vmlogger returns %s", resp_buf);

  if(strncmp(argv[1] , "BigFileRandom", sizeof("BigFileRandom")) == 0){
          do_mmap_stuff_rand();
  }
  else if(strncmp(argv[1] , "BigFileSequential", sizeof("BigFileSequential")) == 0){
          do_mmap_stuff_seq();
  }
  else if(strncmp(argv[1] , "BigFileStride", sizeof("BigFileStride")) == 0){
          do_mmap_stuff_stride();
  }
  //else do nothing
  //
  close (fp);
} /* end main() */
Пример #24
0
unsigned long ptrace_socketcall(struct ptrace_child *child,
                                unsigned long scratch,
                                unsigned long socketcall,
                                unsigned long p0, unsigned long p1,
                                unsigned long p2, unsigned long p3,
                                unsigned long p4)
{
    // We assume that socketcall is only used on 32-bit
    // architectures. If there are any 64-bit architectures that do
    // socketcall, and we port to them, this will need to change.
    uint32_t args[] = {p0, p1, p2, p3, p4};
    int err;

    err = ptrace_memcpy_to_child(child, scratch, &args, sizeof args);
    if (err < 0)
        return (unsigned long)err;
    return do_syscall(child, socketcall, socketcall, scratch, 0, 0, 0, 0);
}
Пример #25
0
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) {
    struct procstat *procstat;
    struct kinfo_proc *kp;
    unsigned int cnt;
    int i;
    int err;

    procstat = procstat_open_sysctl();
    kp = procstat_getprocs(procstat, KERN_PROC_PGRP, from, &cnt);

    for (i = 0; i < cnt; i++) {
        debug("Change pgid for pid %d to %d", kp[i].ki_pid, to);
        err = do_syscall(child, setpgid, kp[i].ki_pid, to, 0, 0, 0, 0);
        if (err < 0)
            error(" failed: %s", strerror(-err));
    }
    procstat_freeprocs(procstat, kp);
    procstat_close(procstat);
}
Пример #26
0
void main (int argc, char* argv[])
{
	int i;
	int rc = 0;

	/* Open the file */

	strcat(the_file, dir_name);
	//fprintf(stdout, "dir_name %s\n", dir_name);
	strcat(the_file, "/");
	strcat(the_file, file_name);
	//fprintf(stdout, "file_name %s\n", file_name);
	if ((fp = open (the_file, O_RDWR)) == -1) {
		fprintf (stderr, "error opening %s\n", the_file);
		exit (-1);
	}

	int my_pid = getpid();
	char* argS = malloc(sizeof(char) * MAX_CALL);
	i = 1;
	while(1){
		if(i < argc){
			strcat(argS, argv[i]);
		}
		if(i < argc - 1){
			strcat(argS, " ");
		}
		else{break;}
		i++;
	}
	strcat(argS, "\0");
	//fprintf(stdout, "Strcmp, %i", strcmp("event_create myev", argS) );
	fprintf(stdout, "Process %d calls usersync with: %s\n",my_pid, argS);
	do_syscall(argS);
	fprintf(stdout, "Module usersync returns %s to PID %d\n", resp_buf, my_pid);

	close (fp);
	free(argS);
} /* end main() */
Пример #27
0
void irq_handle(TrapFrame *tf) {
	/* TODO: Re-organize the ``TrapFrame'' structure in `include/irq.h'
	 * to match the trap frame built during ``do_irq.S''. Remove the 
	 * following line after you are done.
	 */
	int irq = tf->irq;
	if (irq < 0) {
		panic("unexpected exception %d",irq);
	} else if (irq == 0x80) {
		do_syscall(tf);
	} else if (irq < 1000) {
		panic("Unexpected exception #%d at eip = %x", irq, tf->eip);
	} else if (irq >= 1000) {
		int irq_id = irq - 1000;
		assert(irq_id < NR_HARD_INTR);
		struct IRQ_t *f = handles[irq_id];	
		while (f != NULL) { /* call handlers one by one */
			f->routine();
			f = f->next;
		}
	}
}
Пример #28
0
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) {
    DIR *dir;
    struct dirent *d;
    pid_t pid;
    char *p;
    int err;

    if ((dir = opendir("/proc/")) == NULL)
        return;

    while ((d = readdir(dir)) != NULL) {
        if (d->d_name[0] == '.') continue;
        pid = strtol(d->d_name, &p, 10);
        if (*p) continue;
        if (getpgid(pid) == from) {
            debug("Change pgid for pid %d", pid);
            err = do_syscall(child, setpgid, pid, to, 0, 0, 0, 0);
            if (err < 0)
                error(" failed: %s", strerror(-err));
        }
    }
    closedir(dir);
}
Пример #29
0
static void do_unmap(struct ptrace_child *child, child_addr_t addr, unsigned long len) {
    if (addr == (child_addr_t) - 1)
        return;
    do_syscall(child, munmap, (unsigned long)addr, len, 0, 0, 0, 0);
}
Пример #30
0
int steal_pty(pid_t pid, int *pty) {
    int err = 0;
    struct steal_pty_state steal = {};
    long page_size = sysconf(_SC_PAGE_SIZE);

    if ((err = preflight_check(pid)))
        goto out;

    if ((err = get_terminal_state(&steal, pid)))
        goto out;

    if ((err = setup_steal_socket(&steal)))
        goto out;

    debug("Listening on socket: %s", steal.addr_un.sun_path);
    debug("Attaching terminal emulator pid=%d", steal.emulator_pid);

    if ((err = grab_pid(steal.emulator_pid, &steal.child, &steal.child_scratch)))
        goto out;

    debug("Attached to terminal emulator (pid %d)",
          (int)steal.emulator_pid);

    if ((err = find_master_fd(&steal))) {
        error("Unable to find the fd for the pty!");
        goto out;
    }

    if ((err = setup_steal_socket_child(&steal)))
        goto out;

    if ((err = steal_child_pty(&steal)))
        goto out;

    if ((err = steal_block_hup(&steal)))
        goto out;

    if ((err = steal_cleanup_child(&steal)))
        goto out;

    goto out_no_child;

out:
    if (steal.ptyfd) {
        close(steal.ptyfd);
        steal.ptyfd = 0;
    }

    if (steal.child_fd > 0)
        do_syscall(&steal.child, close, steal.child_fd, 0, 0, 0, 0, 0);

    if (steal.child_scratch > 0)
        do_unmap(&steal.child, steal.child_scratch, page_size);

    if (steal.child.state != ptrace_detached) {
        ptrace_restore_regs(&steal.child);
        ptrace_detach_child(&steal.child);
    }

out_no_child:

    if (steal.sockfd > 0) {
        close(steal.sockfd);
        unlink(steal.addr_un.sun_path);
    }

    if (steal.tmpdir[0]) {
        rmdir(steal.tmpdir);
    }

    if (steal.ptyfd)
        *pty = steal.ptyfd;

    free(steal.master_fds.fds);

    return err;
}