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 @@ ...@@ -8,11 +8,13 @@
#include "linux/list.h" #include "linux/list.h"
#include "linux/devfs_fs_kernel.h" #include "linux/devfs_fs_kernel.h"
#include "asm/irq.h" #include "asm/irq.h"
#include "asm/uaccess.h"
#include "chan_kern.h" #include "chan_kern.h"
#include "irq_user.h" #include "irq_user.h"
#include "line.h" #include "line.h"
#include "kern.h" #include "kern.h"
#include "user_util.h" #include "user_util.h"
#include "kern_util.h"
#include "os.h" #include "os.h"
#define LINE_BUFSIZE 4096 #define LINE_BUFSIZE 4096
...@@ -87,15 +89,26 @@ static int flush_buffer(struct line *line) ...@@ -87,15 +89,26 @@ static int flush_buffer(struct line *line)
return(line->head == line->tail); return(line->head == line->tail);
} }
int line_write(struct line *lines, struct tty_struct *tty, const char *buf, int line_write(struct line *lines, struct tty_struct *tty, int from_user,
int len) const char *buf, int len)
{ {
struct line *line; struct line *line;
char *new;
unsigned long flags; unsigned long flags;
int n, err, i; int n, err, i;
if(tty->stopped) return 0; 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; i = minor(tty->device) - tty->driver.minor_start;
line = &lines[i]; line = &lines[i];
...@@ -451,7 +464,7 @@ static void winch_cleanup(void) ...@@ -451,7 +464,7 @@ static void winch_cleanup(void)
list_for_each(ele, &winch_handlers){ list_for_each(ele, &winch_handlers){
winch = list_entry(ele, struct winch, list); winch = list_entry(ele, struct winch, list);
close(winch->fd); 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) ...@@ -99,14 +99,13 @@ static int port_accept(struct port_list *port)
} }
list_add(&conn->list, &port->pending); list_add(&conn->list, &port->pending);
ret = 1; return(1);
goto out;
out_free: out_free:
kfree(conn); kfree(conn);
out_close: out_close:
os_close_file(fd); os_close_file(fd);
if(pid != -1) os_kill_process(pid); if(pid != -1) os_kill_process(pid, 0);
out: out:
return(ret); return(ret);
} }
...@@ -210,9 +209,9 @@ void port_remove_dev(void *d) ...@@ -210,9 +209,9 @@ void port_remove_dev(void *d)
struct port_dev *dev = d; struct port_dev *dev = d;
if(dev->helper_pid != -1) if(dev->helper_pid != -1)
os_kill_process(dev->helper_pid); os_kill_process(dev->helper_pid, 0);
if(dev->telnetd_pid != -1) if(dev->telnetd_pid != -1)
os_kill_process(dev->telnetd_pid); os_kill_process(dev->telnetd_pid, 0);
dev->helper_pid = -1; dev->helper_pid = -1;
} }
...@@ -275,8 +274,8 @@ void port_kern_free(void *d) ...@@ -275,8 +274,8 @@ void port_kern_free(void *d)
{ {
struct port_dev *dev = d; struct port_dev *dev = d;
if(dev->helper_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); if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 0);
kfree(dev); kfree(dev);
} }
......
...@@ -83,12 +83,12 @@ static void ssl_close(struct tty_struct *tty, struct file * filp) ...@@ -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, static int ssl_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count) 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) 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) static void ssl_flush_chars(struct tty_struct *tty)
......
...@@ -120,7 +120,7 @@ static void con_close(struct tty_struct *tty, struct file *filp) ...@@ -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, static int con_write(struct tty_struct *tty, int from_user,
const unsigned char *buf, int count) 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) 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); ...@@ -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 void line_close(struct line *lines, struct tty_struct *tty);
extern int line_open(struct line *lines, struct tty_struct *tty, extern int line_open(struct line *lines, struct tty_struct *tty,
struct chan_opts *opts); struct chan_opts *opts);
extern void line_setup(struct line *lines, int num, char *init); extern int line_setup(struct line *lines, int num, char *init,
extern int line_write(struct line *line, struct tty_struct *tty, int all_allowed);
extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
const char *buf, int len); const char *buf, int len);
extern int line_write_room(struct tty_struct *tty); extern int line_write_room(struct tty_struct *tty);
extern char *add_xterm_umid(char *base); extern char *add_xterm_umid(char *base);
......
...@@ -103,10 +103,16 @@ extern int os_write_file(int fd, char *buf, int count); ...@@ -103,10 +103,16 @@ extern int os_write_file(int fd, char *buf, int count);
extern unsigned long os_process_pc(int pid); extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid); extern int os_process_parent(int pid);
extern void os_stop_process(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 void os_usr1_process(int pid);
extern int os_getpid(void); 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 #endif
/* /*
......
...@@ -43,9 +43,12 @@ static int helper_child(void *arg) ...@@ -43,9 +43,12 @@ static int helper_child(void *arg)
execvp(argv[0], argv); execvp(argv[0], argv);
printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
write(data->fd, &errno, sizeof(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, int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
unsigned long *stack_out) unsigned long *stack_out)
{ {
......
...@@ -164,19 +164,18 @@ static int ptrace_child(void *arg) ...@@ -164,19 +164,18 @@ static int ptrace_child(void *arg)
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
perror("ptrace"); perror("ptrace");
_exit(1); os_kill_process(pid, 0);
} }
os_stop_process(pid); os_stop_process(pid);
_exit(os_getpid() == pid); _exit(os_getpid() == pid);
} }
void __init check_ptrace(void) static int start_ptraced_child(void **stack_out)
{ {
void *stack; void *stack;
unsigned long sp; unsigned long sp;
int status, pid, n, syscall; int pid, n, status;
printk("Checking that ptrace can change system call numbers...");
stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(stack == MAP_FAILED) if(stack == MAP_FAILED)
...@@ -191,6 +190,33 @@ void __init check_ptrace(void) ...@@ -191,6 +190,33 @@ void __init check_ptrace(void)
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
panic("check_ptrace : expected SIGSTOP, got status = %d", panic("check_ptrace : expected SIGSTOP, got status = %d",
status); 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){ while(1){
if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", panic("check_ptrace : ptrace failed, errno = %d",
...@@ -213,23 +239,19 @@ void __init check_ptrace(void) ...@@ -213,23 +239,19 @@ void __init check_ptrace(void)
break; break;
} }
} }
if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) stop_ptraced_child(pid, stack, 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);
printk("OK\n"); printk("OK\n");
} }
int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
{ {
jmp_buf buf; jmp_buf buf;
int n;
*jmp_ptr = &buf; *jmp_ptr = &buf;
if(setjmp(buf)) return(1); n = setjmp(buf);
if(n != 0)
return(n);
(*fn)(arg); (*fn)(arg);
return(0); return(0);
} }
...@@ -244,6 +266,65 @@ void forward_pending_sigio(int target) ...@@ -244,6 +266,65 @@ void forward_pending_sigio(int target)
kill(target, SIGIO); 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. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -21,13 +21,12 @@ ...@@ -21,13 +21,12 @@
void set_sigstack(void *sig_stack, int size) 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) 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, ...) void set_handler(int sig, void (*handler)(int), int flags, ...)
...@@ -103,6 +102,15 @@ int get_signals(void) ...@@ -103,6 +102,15 @@ int get_signals(void)
return(enable_mask(&mask)); 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) int set_signals(int enable)
{ {
sigset_t mask; sigset_t mask;
......
...@@ -75,9 +75,12 @@ void os_stop_process(int pid) ...@@ -75,9 +75,12 @@ void os_stop_process(int pid)
kill(pid, SIGSTOP); kill(pid, SIGSTOP);
} }
void os_kill_process(int pid) void os_kill_process(int pid, int reap_child)
{ {
kill(pid, SIGKILL); kill(pid, SIGKILL);
if(reap_child)
waitpid(pid, NULL, 0);
} }
void os_usr1_process(int pid) 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