gBootRoot pronounced "bOOtrOOt"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

183 lines
3.7 KiB

/*
skas_or_tt Copyright (C) 2003
Jonathan Rosenbaum <freesource@users.sourceforge.net>
A program to check for the existence of the skas patch in the host
kernel and /proc/mm. Basically borrowed/simplified from jdike's
process.c. This is a good way to learn about clone() and ptrace().
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <wait.h>
#include <sys/mman.h> /* for mmap */
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sched.h> /* clone */
#define PTRACE_FAULTINFO 52
#define PAGE_SIZE 1024
int main(void)
{
int n, pid, ret = 1, cmdline_value;
void *stack;
struct ptrace_faultinfo {
int is_write;
unsigned long addr;
};
struct ptrace_faultinfo fi;
cmdline_value = host_cmdline();
if ( cmdline_value == 1 ) {
printf("Checking for the skas3 patch in the host...not found\nChecking for /proc/mm...not found\n");
kill(pid, SIGSTOP);
kill(pid, SIGKILL);
return(0);
}
else if ( cmdline_value == 2 ) {
printf("Checking for the skas3 patch in the host...found\nChecking for /proc/mm...found\n");
kill(pid, SIGSTOP);
kill(pid, SIGKILL);
return(0);
}
printf("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)
printf("not found\n");
else printf("No (unexpected errno - %d)\n", errno);
ret = 0;
}
else printf("found\n");
printf("Checking for /proc/mm...");
if(access("/proc/mm", W_OK)){
printf("not found\n");
ret = 0;
}
else printf("found\n");
kill(pid, SIGSTOP);
kill(pid, SIGKILL);
return(ret);
}
int host_cmdline (void)
{
char s[500]; /* should be the max cmdline size */
FILE *f;
char *tt = "mode=tt";
char *skas = "mode=skas";
char *ptt, *pskas;
f = fopen("/proc/cmdline","r");
if ( f == NULL ) {
printf("Error: unable to open /proc/cmdline for reading\n");
return(0);
}
if (fgets(s, sizeof s, f) != NULL) {
ptt = strstr(s, tt);
pskas = strstr(s, skas);
if ( ptt != NULL )
return(1);
else if ( pskas != NULL )
return(2);
else
return(0);
}
return(1); /* safety default */
}
int os_getpid(void)
{
return(getpid());
}
void os_stop_process(int pid)
{
kill(pid, SIGSTOP);
}
void os_kill_process(int pid, int reap_child)
{
kill(pid, SIGKILL);
if(reap_child)
waitpid(pid, NULL, 0);
}
static int ptrace_child(void *arg)
{
int pid = os_getpid();
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
perror("ptrace");
os_kill_process(pid, 0);
}
os_stop_process(pid);
_exit(os_getpid() == pid);
}
int start_ptraced_child(void **stack_out)
{
void *stack;
unsigned long sp;
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)
printf("check_ptrace : mmap failed, errno = %d", errno);
sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
if(pid < 0) {
printf("check_ptrace : clone failed, errno = %d\n", errno);
exit(0);
}
n = waitpid(pid, &status, WUNTRACED);
if(n < 0) {
printf("check_ptrace : wait failed, errno = %d\n", errno);
exit(0);
}
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
printf("check_ptrace : expected SIGSTOP, got status = %d\n",
status);
exit(0);
}
*stack_out = stack;
return(pid);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/