Skip to content

Commit a456862

Browse files
IgorIgor
authored andcommitted
Adding ctl file, basic implementation of stop, start and signalwait
1 parent 7b9f4fc commit a456862

File tree

6 files changed

+106
-12
lines changed

6 files changed

+106
-12
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
VERSION = 3
22
PATCHLEVEL = 1
33
SUBLEVEL = 0
4-
EXTRAVERSION = -rc8
5-
NAME = "Divemaster Edition"
4+
EXTRAVERSION = -hack2
5+
NAME = "Igor's h4x0r kernel"
66

77
# *DOCUMENTATION*
88
# To see a list of typical targets execute "make help"

fs/proc/base.c

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@
6565
#include <linux/mm.h>
6666
#include <linux/swap.h>
6767
#include <linux/rcupdate.h>
68+
#include <linux/wait.h>
69+
#include <linux/list.h>
6870
#include <linux/kallsyms.h>
6971
#include <linux/stacktrace.h>
7072
#include <linux/resource.h>
7173
#include <linux/module.h>
7274
#include <linux/mount.h>
7375
#include <linux/security.h>
74-
#include <linux/ptrace.h>
7576
#include <linux/tracehook.h>
7677
#include <linux/cgroup.h>
7778
#include <linux/cpuset.h>
@@ -209,16 +210,8 @@ static struct mm_struct *__check_mem_permission(struct task_struct *task)
209210
if (task == current)
210211
return mm;
211212

212-
/*
213-
* If current is actively ptrace'ing, and would also be
214-
* permitted to freshly attach with ptrace now, permit it.
215-
*/
216213
if (task_is_stopped_or_traced(task)) {
217-
int match;
218-
rcu_read_lock();
219-
match = (ptrace_parent(task) == current);
220-
rcu_read_unlock();
221-
if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
214+
if (ptrace_may_access(task, PTRACE_MODE_ATTACH))
222215
return mm;
223216
}
224217

@@ -966,6 +959,83 @@ static const struct file_operations proc_mem_operations = {
966959
.open= mem_open,
967960
};
968961

962+
static int ctl_stop(struct task_struct *task)
963+
{
964+
printk("PROCTRACE stopping %d task with %d\n", task->pid, current->pid);
965+
send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
966+
return 0;
967+
}
968+
969+
static int ctl_start(struct task_struct *task) {
970+
printk("PROCTRACE continuing %d task with %d\n", task->pid, current->pid);
971+
wake_up_process(task);
972+
return 0;
973+
}
974+
975+
static int ctl_waitsignal(struct task_struct *task, int sigmask) {
976+
struct sig_wait_queue_struct *sig_wait;
977+
DEFINE_WAIT(wait);
978+
int retval = 0;
979+
980+
printk("PROCTRACE waiting %d task with %d. sigmask %d\n", task->pid, current->pid, sigmask);
981+
982+
printk("Allocating new signal wait queue\n");
983+
sig_wait = kmalloc(sizeof(struct sig_wait_queue_struct), GFP_KERNEL);
984+
if (!sig_wait) {
985+
retval = -ENOMEM;
986+
goto done;
987+
}
988+
sig_wait->sigmask = sigmask;
989+
init_waitqueue_head(&sig_wait->wait_queue);
990+
991+
write_lock(&tasklist_lock);
992+
list_add(&sig_wait->list, &task->sig_wait_list);
993+
write_unlock(&tasklist_lock);
994+
995+
prepare_to_wait(&sig_wait->wait_queue, &wait, TASK_INTERRUPTIBLE);
996+
schedule();
997+
finish_wait(&sig_wait->wait_queue, &wait);
998+
999+
write_lock(&tasklist_lock);
1000+
list_del(&sig_wait->list);
1001+
write_unlock(&tasklist_lock);
1002+
1003+
kfree(sig_wait);
1004+
1005+
done:
1006+
return retval;
1007+
}
1008+
1009+
static ssize_t ctl_write(struct file * file, const char __user *buf,
1010+
size_t count, loff_t *ppos)
1011+
{
1012+
int tmp, i;
1013+
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
1014+
1015+
if (strncmp(buf, "stop", 4) == 0) {
1016+
ctl_stop(task);
1017+
} else if (strncmp(buf, "start", 5) == 0) {
1018+
ctl_start(task);
1019+
} else if (strncmp(buf, "waitsignal", 10) == 0) {
1020+
tmp = 0;
1021+
for (i = 11; i < count; ++i) {
1022+
if (buf[i] == '1' || buf[i] == '0') {
1023+
tmp = tmp * 2 + (int)(buf[i]-'0');
1024+
} else if (buf[i] != ' ') {
1025+
break;
1026+
}
1027+
}
1028+
1029+
ctl_waitsignal(task, tmp);
1030+
}
1031+
1032+
return count;
1033+
}
1034+
1035+
static const struct file_operations proc_ctl_operations = {
1036+
.write= ctl_write,
1037+
};
1038+
9691039
static ssize_t environ_read(struct file *file, char __user *buf,
9701040
size_t count, loff_t *ppos)
9711041
{
@@ -2813,6 +2883,7 @@ static const struct pid_entry tgid_base_stuff[] = {
28132883
REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
28142884
#endif
28152885
REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2886+
REG("ctl", S_IWUSR, proc_ctl_operations),
28162887
LNK("cwd", proc_cwd_link),
28172888
LNK("root", proc_root_link),
28182889
LNK("exe", proc_exe_link),

include/linux/init_task.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ extern struct cred init_cred;
155155
INIT_PUSHABLE_TASKS(tsk) \
156156
.ptraced = LIST_HEAD_INIT(tsk.ptraced), \
157157
.ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \
158+
.sig_wait_list = LIST_HEAD_INIT(tsk.sig_wait_list), \
158159
.real_parent = &tsk, \
159160
.parent = &tsk, \
160161
.children = LIST_HEAD_INIT(tsk.children), \

include/linux/sched.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,14 @@ enum perf_event_task_context {
12171217
perf_nr_task_contexts,
12181218
};
12191219

1220+
struct sig_wait_queue_struct {
1221+
int sigmask;
1222+
/* actual wait queue -> can have only one element in it */
1223+
wait_queue_head_t wait_queue;
1224+
/* all other signal queues for this task */
1225+
struct list_head list;
1226+
};
1227+
12201228
struct task_struct {
12211229
volatile long state;/* -1 unrunnable, 0 runnable, >0 stopped */
12221230
void *stack;
@@ -1335,6 +1343,8 @@ struct task_struct {
13351343
struct list_head ptraced;
13361344
struct list_head ptrace_entry;
13371345

1346+
struct list_head sig_wait_list;
1347+
13381348
/* PID/PID hash table linkage. */
13391349
struct pid_link pids[PIDTYPE_MAX];
13401350
struct list_head thread_group;

kernel/fork.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
13021302
p->pdeath_signal = 0;
13031303
p->exit_state = 0;
13041304

1305+
/* Initialize signal wait queue list */
1306+
INIT_LIST_HEAD(&p->sig_wait_list);
1307+
13051308
/*
13061309
* Ok, make it visible to the rest of the system.
13071310
* We dont wake it up yet.

kernel/signal.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
15891589
*/
15901590
bool do_notify_parent(struct task_struct *tsk, int sig)
15911591
{
1592+
struct list_head *p;
15921593
struct siginfo info;
15931594
unsigned long flags;
15941595
struct sighand_struct *psig;
@@ -1663,6 +1664,14 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
16631664
if (valid_signal(sig) && sig)
16641665
__group_send_sig_info(sig, &info, tsk->parent);
16651666
__wake_up_parent(tsk, tsk->parent);
1667+
1668+
/* also notify all the proctraces */
1669+
list_for_each(p, &tsk->sig_wait_list) {
1670+
wake_up(&list_entry(
1671+
p, struct sig_wait_queue_struct,
1672+
list)->wait_queue);
1673+
}
1674+
16661675
spin_unlock_irqrestore(&psig->siglock, flags);
16671676

16681677
return autoreap;

0 commit comments

Comments
 (0)