cregit-Linux how code gets into the kernel

Release 4.7 arch/cris/arch-v10/kernel/ptrace.c

/*
 * Copyright (C) 2000-2003, Axis Communications AB.
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
#include <linux/security.h>

#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/processor.h>

/* 
 * Determines which bits in DCCR the user has access to.
 * 1 = access, 0 = no access.
 */

#define DCCR_MASK 0x0000001f     
/* XNZVC */

/*
 * Get contents of register REGNO in task TASK.
 */

inline long get_reg(struct task_struct *task, unsigned int regno) { /* USP is a special case, it's not in the pt_regs struct but * in the tasks thread struct */ if (regno == PT_USP) return task->thread.usp; else if (regno < PT_MAX) return ((unsigned long *)task_pt_regs(task))[regno]; else return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik5598.21%266.67%
al viroal viro11.79%133.33%
Total56100.00%3100.00%

/* * Write contents of register REGNO in task TASK. */
inline int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) { if (regno == PT_USP) task->thread.usp = data; else if (regno < PT_MAX) ((unsigned long *)task_pt_regs(task))[regno] = data; else return -1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik6498.46%266.67%
al viroal viro11.54%133.33%
Total65100.00%3100.00%

/* * Called by kernel/ptrace.c when detaching. * * Make sure the single step bit is not set. */
void ptrace_disable(struct task_struct *child) { /* Todo - pending singlesteps? */ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); }

Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik1161.11%150.00%
jesper nilssonjesper nilsson738.89%150.00%
Total18100.00%2100.00%

/* * Note that this implementation of ptrace behaves differently from vanilla * ptrace. Contrary to what the man page says, in the PTRACE_PEEKTEXT, * PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not * ignored. Instead, the data variable is expected to point at a location * (in user space) where the result of the ptrace call is written (instead of * being returned). */
long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { int ret; unsigned int regno = addr >> 2; unsigned long __user *datap = (unsigned long __user *)data; switch (request) { /* Read word at location address. */ case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: ret = generic_ptrace_peekdata(child, addr, data); break; /* Read the word at location address in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; ret = -EIO; if ((addr & 3) || regno > PT_MAX) break; tmp = get_reg(child, regno); ret = put_user(tmp, datap); break; } /* Write the word at location address. */ case PTRACE_POKETEXT: case PTRACE_POKEDATA: ret = generic_ptrace_pokedata(child, addr, data); break; /* Write the word at location address in the USER area. */ case PTRACE_POKEUSR: ret = -EIO; if ((addr & 3) || regno > PT_MAX) break; if (regno == PT_DCCR) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ data &= DCCR_MASK; data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } if (put_reg(child, regno, data)) break; ret = 0; break; /* Get all GP registers from the child. */ case PTRACE_GETREGS: { int i; unsigned long tmp; ret = 0; for (i = 0; i <= PT_MAX; i++) { tmp = get_reg(child, i); if (put_user(tmp, datap)) { ret = -EFAULT; break; } datap++; } break; } /* Set all GP registers in the child. */ case PTRACE_SETREGS: { int i; unsigned long tmp; ret = 0; for (i = 0; i <= PT_MAX; i++) { if (get_user(tmp, datap)) { ret = -EFAULT; break; } if (i == PT_DCCR) { tmp &= DCCR_MASK; tmp |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } put_reg(child, i, tmp); datap++; } break; } default: ret = ptrace_request(child, request, addr, data); break; } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik32287.74%222.22%
namhyung kimnamhyung kim195.18%222.22%
al viroal viro102.72%111.11%
christoph hellwigchristoph hellwig71.91%111.11%
andrew mortonandrew morton51.36%111.11%
alexey dobriyanalexey dobriyan41.09%222.22%
Total367100.00%9100.00%


void do_syscall_trace(void) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; if (!(current->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); /* * This isn't the same as continuing with a signal, but it will do for * normal use. */ if (current->exit_code) { send_sig(current->exit_code, current, 1); current->exit_code = 0; } }

Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik7195.95%150.00%
andrew mortonandrew morton34.05%150.00%
Total74100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
mikael starvikmikael starvik57090.48%323.08%
namhyung kimnamhyung kim193.02%215.38%
al viroal viro121.90%215.38%
andrew mortonandrew morton81.27%17.69%
jesper nilssonjesper nilsson71.11%17.69%
christoph hellwigchristoph hellwig71.11%17.69%
alexey dobriyanalexey dobriyan40.63%215.38%
jesper juhljesper juhl30.48%17.69%
Total630100.00%13100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}