Commit 952b67f1 authored by Jeff Dike's avatar Jeff Dike

Merged the os_kill_process and the driver from_user changes from

the 2.4 pool.
Also merged some other cleanups.
parent 8c04ef75
......@@ -8,11 +8,13 @@
#include "linux/list.h"
#include "linux/devfs_fs_kernel.h"
#include "asm/irq.h"
#include "asm/uaccess.h"
#include "chan_kern.h"
#include "irq_user.h"
#include "line.h"
#include "kern.h"
#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#define LINE_BUFSIZE 4096
......@@ -87,15 +89,26 @@ static int flush_buffer(struct line *line)
return(line->head == line->tail);
}
int line_write(struct line *lines, struct tty_struct *tty, const char *buf,
int len)
int line_write(struct line *lines, struct tty_struct *tty, int from_user,
const char *buf, int len)
{
struct line *line;
char *new;
unsigned long flags;
int n, err, i;
if(tty->stopped) return 0;
if(from_user){
new = kmalloc(len, GFP_KERNEL);
if(new == NULL)
return(0);
n = copy_from_user(new, buf, len);
if(n == len)
return(-EFAULT);
buf = new;
}
i = minor(tty->device) - tty->driver.minor_start;
line = &lines[i];
......@@ -451,7 +464,7 @@ static void winch_cleanup(void)
list_for_each(ele, &winch_handlers){
winch = list_entry(ele, struct winch, list);
close(winch->fd);
if(winch->pid != -1) os_kill_process(winch->pid);
if(winch->pid != -1) os_kill_process(winch->pid, 0);
}
}
......
......@@ -99,14 +99,13 @@ static int port_accept(struct port_list *port)
}
list_add(&conn->list, &port->pending);
ret = 1;
goto out;
return(1);
out_free:
kfree(conn);
out_close:
os_close_file(fd);
if(pid != -1) os_kill_process(pid);
if(pid != -1) os_kill_process(pid, 0);
out:
return(ret);
}
......@@ -210,9 +209,9 @@ void port_remove_dev(void *d)
struct port_dev *dev = d;
if(dev->helper_pid != -1)
os_kill_process(dev->helper_pid);
os_kill_process(dev->helper_pid, 0);
if(dev->telnetd_pid != -1)
os_kill_process(dev->telnetd_pid);
os_kill_process(dev->telnetd_pid, 0);
dev->helper_pid = -1;
}
......@@ -275,8 +274,8 @@ void port_kern_free(void *d)
{
struct port_dev *dev = d;
if(dev->helper_pid != -1) os_kill_process(dev->telnetd_pid);
if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid);
if(dev->helper_pid != -1) os_kill_process(dev->helper_pid, 0);
if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 0);
kfree(dev);
}
......
......@@ -83,12 +83,12 @@ static void ssl_close(struct tty_struct *tty, struct file * filp)
static int ssl_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
return(line_write(serial_lines, tty, buf, count));
return(line_write(serial_lines, tty, from_user, buf, count));
}
static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
{
line_write(serial_lines, tty, &ch, sizeof(ch));
line_write(serial_lines, tty, 0, &ch, sizeof(ch));
}
static void ssl_flush_chars(struct tty_struct *tty)
......
......@@ -120,7 +120,7 @@ static void con_close(struct tty_struct *tty, struct file *filp)
static int con_write(struct tty_struct *tty, int from_user,
const unsigned char *buf, int count)
{
return(line_write(vts, tty, buf, count));
return(line_write(vts, tty, from_user, buf, count));
}
static void set_termios(struct tty_struct *tty, struct termios * old)
......
......@@ -70,8 +70,9 @@ extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
extern void line_close(struct line *lines, struct tty_struct *tty);
extern int line_open(struct line *lines, struct tty_struct *tty,
struct chan_opts *opts);
extern void line_setup(struct line *lines, int num, char *init);
extern int line_write(struct line *line, struct tty_struct *tty,
extern int line_setup(struct line *lines, int num, char *init,
int all_allowed);
extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
const char *buf, int len);
extern int line_write_room(struct tty_struct *tty);
extern char *add_xterm_umid(char *base);
......
......@@ -103,10 +103,16 @@ extern int os_write_file(int fd, char *buf, int count);
extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_usr1_process(int pid);
extern int os_getpid(void);
extern int os_map_memory(void *virt, int fd, unsigned long off,
unsigned long len, int r, int w, int x);
extern int os_protect_memory(void *addr, unsigned long len,
int r, int w, int x);
extern int os_unmap_memory(void *addr, int len);
#endif
/*
......
......@@ -43,9 +43,12 @@ static int helper_child(void *arg)
execvp(argv[0], argv);
printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
write(data->fd, &errno, sizeof(errno));
_exit(1);
os_kill_process(os_getpid(), 0);
return(0);
}
/* XXX The alloc_stack here breaks if this is called in the tracing thread */
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
unsigned long *stack_out)
{
......
......@@ -164,19 +164,18 @@ static int ptrace_child(void *arg)
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
perror("ptrace");
_exit(1);
os_kill_process(pid, 0);
}
os_stop_process(pid);
_exit(os_getpid() == pid);
}
void __init check_ptrace(void)
static int start_ptraced_child(void **stack_out)
{
void *stack;
unsigned long sp;
int status, pid, n, syscall;
printk("Checking that ptrace can change system call numbers...");
int pid, n, status;
stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(stack == MAP_FAILED)
......@@ -191,6 +190,33 @@ void __init check_ptrace(void)
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
panic("check_ptrace : expected SIGSTOP, got status = %d",
status);
*stack_out = stack;
return(pid);
}
static void stop_ptraced_child(int pid, void *stack, int exitcode)
{
int status, n;
if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", errno);
n = waitpid(pid, &status, 0);
if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
panic("check_ptrace : child exited with status 0x%x", status);
if(munmap(stack, PAGE_SIZE) < 0)
panic("check_ptrace : munmap failed, errno = %d", errno);
}
void __init check_ptrace(void)
{
void *stack;
int pid, syscall, n, status;
printk("Checking that ptrace can change system call numbers...");
pid = start_ptraced_child(&stack);
while(1){
if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d",
......@@ -213,23 +239,19 @@ void __init check_ptrace(void)
break;
}
}
if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", errno);
n = waitpid(pid, &status, 0);
if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
panic("check_ptrace : child exited with status 0x%x", status);
if(munmap(stack, PAGE_SIZE) < 0)
panic("check_ptrace : munmap failed, errno = %d", errno);
stop_ptraced_child(pid, stack, 0);
printk("OK\n");
}
int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
{
jmp_buf buf;
int n;
*jmp_ptr = &buf;
if(setjmp(buf)) return(1);
n = setjmp(buf);
if(n != 0)
return(n);
(*fn)(arg);
return(0);
}
......@@ -244,6 +266,65 @@ void forward_pending_sigio(int target)
kill(target, SIGIO);
}
#ifdef CONFIG_MODE_SKAS
static void init_registers(int pid)
{
int err;
if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
if(!err)
return;
have_fpx_regs = 0;
if(errno != EIO)
panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
errno);
}
#endif
int can_do_skas(void)
{
struct ptrace_faultinfo fi;
void *stack;
int pid, n, ret = 1;
printk("Checking for the skas3 patch in the host...");
pid = start_ptraced_child(&stack);
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
if(n < 0){
if(errno == EIO)
printk("not found\n");
else printk("No (unexpected errno - %d)\n", errno);
ret = 0;
}
else printk("found\n");
init_registers(pid);
stop_ptraced_child(pid, stack, 1);
printk("Checking for /proc/mm...");
if(access("/proc/mm", W_OK)){
printk("not found\n");
ret = 0;
}
else printk("found\n");
return(ret);
#else
return(0);
#endif
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
......
......@@ -21,13 +21,12 @@
void set_sigstack(void *sig_stack, int size)
{
stack_t stack;
stack_t stack = ((stack_t) { .ss_flags = 0,
.ss_sp = (__ptr_t) sig_stack,
.ss_size = size - sizeof(void *) });
stack.ss_sp = (__ptr_t) sig_stack;
stack.ss_flags = 0;
stack.ss_size = size - sizeof(void *);
if(sigaltstack(&stack, NULL) != 0)
panic("sigaltstack failed");
panic("enabling signal stack failed, errno = %d\n", errno);
}
void set_handler(int sig, void (*handler)(int), int flags, ...)
......@@ -103,6 +102,15 @@ int get_signals(void)
return(enable_mask(&mask));
}
int get_signals(void)
{
sigset_t mask;
if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
panic("Failed to get signal mask");
return(enable_mask(&mask));
}
int set_signals(int enable)
{
sigset_t mask;
......
......@@ -75,9 +75,12 @@ void os_stop_process(int pid)
kill(pid, SIGSTOP);
}
void os_kill_process(int pid)
void os_kill_process(int pid, int reap_child)
{
kill(pid, SIGKILL);
if(reap_child)
waitpid(pid, NULL, 0);
}
void os_usr1_process(int pid)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment