Example #1
0
static int ptrace_detach(struct task_struct *child, unsigned int data)
{
	bool dead = false;

	if (!valid_signal(data))
		return -EIO;

	/* Architecture-specific hardware disable .. */
	ptrace_disable(child);
	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);

	write_lock_irq(&tasklist_lock);
	/*
	 * This child can be already killed. Make sure de_thread() or
	 * our sub-thread doing do_wait() didn't do release_task() yet.
	 */
	if (child->ptrace) {
		child->exit_code = data;
		dead = __ptrace_detach(current, child);
	}
	write_unlock_irq(&tasklist_lock);

	if (unlikely(dead))
		release_task(child);

	return 0;
}
Example #2
0
SYSCALL_DEFINE2( smunch, int, pid, unsigned long, bit_pattern) {
	struct task_struct *target;
	unsigned long flags;
	rcu_read_lock();
	target=find_task_by_vpid(pid);
	rcu_read_unlock();
	if(!target) {
	printk(KERN_ALERT "TARGET DOESNT EXIST\n"); 
	return -1;}
	
	if(!lock_task_sighand(target, &flags)) {
        printk(KERN_ALERT "Could not acquire sighand lock\n");
        return -1;}
	if(!thread_group_empty(target)) {
                printk(KERN_ALERT "Multi threaded process\n");
		unlock_task_sighand(target , &flags);
		return -1;
	}
	if((target->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) && (bit_pattern & (1<<(SIGKILL-1)))) {
		printk(KERN_ALERT " killing process with PID %d\n",pid);
		unlock_task_sighand(target, &flags);
		release_task(target);
	}
	else {
                sigaddsetmask(&(target->signal->shared_pending.signal),bit_pattern);
			wake_up_process(target);
		unlock_task_sighand(target, &flags);
	}
	return 0;
}
Example #3
0
SYSCALL_DEFINE2(smunch, pid_t,pid, long, bit_pattern){
//Check if multi threaded
  struct task_struct *p;
  bool ret;
  p = pid_task(find_vpid(pid), PIDTYPE_PID);
  if(!p){
    pr_alert("\nprocess table is null");
    return -1;
  }
  ret = current_is_single_threaded();
  if(ret == false){
    pr_alert("\nError : Multithreaded process, cannot proceed\n");
    return -1;
  }
  
//Check if traced
  if(p->ptrace & PT_PTRACED){
    pr_alert("\nError : Traced process, cannot proceed\n");
    return -1;
  }

//Check if zombie state 
  if(p->exit_state == EXIT_ZOMBIE){
    if((1 << (SIGKILL-1)) & bit_pattern){
      release_task(p);
    }
    return 0;
  }
  else{
    p->pending.signal.sig[0] |= bit_pattern;
    wake_up_process(p);
  }
return 0;
}
Example #4
0
int ptrace_detach(struct task_struct *child, unsigned int data)
{
	int dead = 0;

	if (!valid_signal(data))
		return -EIO;

	/* Architecture-specific hardware disable .. */
	ptrace_disable(child);
	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);

	write_lock_irq(&tasklist_lock);
	/* protect against de_thread()->release_task() */
	if (child->ptrace) {
		child->exit_code = data;

		dead = __ptrace_detach(current, child);

		if (!child->exit_state)
			wake_up_process(child);
	}
	write_unlock_irq(&tasklist_lock);

	if (unlikely(dead))
		release_task(child);

	return 0;
}
Example #5
0
SYSCALL_DEFINE2(smunch,int,pid,unsigned long,bit_pattern)
{
	unsigned long flags;	
	struct task_struct *task; 		
		
	rcu_read_lock();
		task = pid_task(find_vpid(pid),PIDTYPE_PID);
	rcu_read_unlock();	
	if(!task) return -1;	 // Process not present
	if(!lock_task_sighand(task,&flags))
	{
		//Process refuses to give the lock. Either dead/dying 
		unlock_task_sighand(task,&flags);
		return -1;		
	}
			
	if(!thread_group_empty(task))
	{
		printk(KERN_ALERT "\nMULTI-Threaded Process, Exiting without processing");
		ret=-1; goto return_path;
	}
	printk(KERN_ALERT "\nExit State:%XH,State=%XH\n",task->exit_state,task->state);	//Info to user
	if(task->state & TASK_UNINTERRUPTIBLE)
	printk(KERN_ALERT "\nProcess is in Uniterruptible Wait-DeepSleep!!"); // Info to User	
	if(bit_pattern & (1UL<<(SIGKILL-1)) && (task->exit_state & EXIT_ZOMBIE))
	{ 
		printk(KERN_ALERT "\nSIGKILL present while Process is Zombie, releasing task!!");		
		unlock_task_sighand(task,&flags);	 	
		release_task(task);  // detach_pid is called from release_task()
		return 0; 
	}
	 /* If !SIGKILL || (ordinary process) || DeepSleep, sending all signals. It is Users responsility to note that signals will get handled from 1-64 order*/
	printk(KERN_ALERT "!SIGKILL || (ordinary process) || DeepSleep, sending all signals!");
	task->signal->shared_pending.signal.sig[0] = bit_pattern;
	set_tsk_thread_flag(task,TIF_SIGPENDING);	
	signal_wake_up(task,1); 
	ret=0;		
	return_path:
	unlock_task_sighand(task,&flags);
	return ret;
}
Example #6
0
int __KT_try_releasing_tasks()
{
	struct llistnode *cur;
	rwlock_acquire(&kill_queue->rwl, RWL_WRITER);
	if(ll_is_empty(kill_queue))
	{
		rwlock_release(&kill_queue->rwl, RWL_WRITER);
		return 0;
	}
	task_t *t=0;
	ll_for_each_entry(kill_queue, cur, task_t *, t)
	{
		/* need to check for orphaned zombie tasks */
		if(t->flags & TF_BURIED && (t != ((cpu_t *)t->cpu)->cur)) {
			if(t->parent == 0 || t->parent->state == TASK_DEAD || (t->parent->flags & TF_KTASK) || t->parent == kernel_task)
				move_task_to_kill_queue(t, 0);
			if(t->flags & TF_KILLREADY)
				break;
		}
	}
	if(!t || !((t->flags & TF_BURIED) && (t->flags & TF_KILLREADY)))
	{
		rwlock_release(&kill_queue->rwl, RWL_WRITER);
		return 0;
	}
	assert(cur->entry == t);
	void *node = ll_do_remove(kill_queue, cur, 1);
	assert(node == cur);
	int ret = 0;
	if(!ll_is_empty(kill_queue))
		ret = 1;
	rwlock_release(&kill_queue->rwl, RWL_WRITER);
	release_task(t);
	kfree(cur);
	return ret;
}
Example #7
0
asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
{
	int flag, retval;
	DECLARE_WAITQUEUE(wait, current);
	struct task_struct *tsk;

	if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL))
		return -EINVAL;

	add_wait_queue(&current->wait_chldexit,&wait);
repeat:
	flag = 0;
	current->state = TASK_INTERRUPTIBLE;
	read_lock(&tasklist_lock);
	tsk = current;
	do {
		struct task_struct *p;
	 	for (p = tsk->p_cptr ; p ; p = p->p_osptr) {
			if (pid>0) {
				if (p->pid != pid)
					continue;
			} else if (!pid) {
				if (p->pgrp != current->pgrp)
					continue;
			} else if (pid != -1) {
				if (p->pgrp != -pid)
					continue;
			}
			/* Wait for all children (clone and not) if __WALL is set;
			 * otherwise, wait for clone children *only* if __WCLONE is
			 * set; otherwise, wait for non-clone children *only*.  (Note:
			 * A "clone" child here is one that reports to its parent
			 * using a signal other than SIGCHLD.) */
			if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
			    && !(options & __WALL))
				continue;
			flag = 1;
			switch (p->state) {
			case TASK_STOPPED:
				if (!p->exit_code)
					continue;
				if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))
					continue;
				read_unlock(&tasklist_lock);
				retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 
				if (!retval && stat_addr) 
					retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
				if (!retval) {
					p->exit_code = 0;
					retval = p->pid;
				}
				goto end_wait4;
			case TASK_ZOMBIE:
				current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
				current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
				read_unlock(&tasklist_lock);
				retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
				if (!retval && stat_addr)
					retval = put_user(p->exit_code, stat_addr);
				if (retval)
					goto end_wait4; 
				retval = p->pid;
				if (p->p_opptr != p->p_pptr) {
					write_lock_irq(&tasklist_lock);
					REMOVE_LINKS(p);
					p->p_pptr = p->p_opptr;
					SET_LINKS(p);
					do_notify_parent(p, SIGCHLD);
					write_unlock_irq(&tasklist_lock);
				} else
					release_task(p);
				goto end_wait4;
			default:
				continue;
			}
		}
		if (options & __WNOTHREAD)
			break;
		tsk = next_thread(tsk);
	} while (tsk != current);
	read_unlock(&tasklist_lock);
	if (flag) {
		retval = 0;
		if (options & WNOHANG)
			goto end_wait4;
		retval = -ERESTARTSYS;
		if (signal_pending(current))
			goto end_wait4;
		schedule();
		goto repeat;
	}
	retval = -ECHILD;
end_wait4:
	current->state = TASK_RUNNING;
	remove_wait_queue(&current->wait_chldexit,&wait);
	return retval;
}
Example #8
0
static void exit_notify(struct task_struct *tsk)
{
	//...
	if (state == TASK_DEAD)
		release_task(tsk);
}