Skip to content

Commit 4027c0f

Browse files
committed
Add wait file
1 parent 63d8b7a commit 4027c0f

File tree

7 files changed

+69
-68
lines changed

7 files changed

+69
-68
lines changed

fs/proc/base.c

Lines changed: 42 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include <linux/cpuset.h>
7979
#include <linux/audit.h>
8080
#include <linux/poll.h>
81+
#include <linux/ptrace.h>
8182
#include <linux/nsproxy.h>
8283
#include <linux/oom.h>
8384
#include <linux/elf.h>
@@ -959,47 +960,44 @@ static const struct file_operations proc_mem_operations = {
959960
.open= mem_open,
960961
};
961962

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, int start_the_task) {
963+
static int wait_waitsignal(struct task_struct *task, unsigned long long mask) {
976964
struct sig_wait_queue_struct *sig_wait;
977965
DEFINE_WAIT(wait);
978966
int retval = 0;
979967

980-
printk("PROCTRACE waiting %d task with %d. sigmask %d\n", task->pid, current->pid, sigmask);
968+
printk("PROCTRACE waiting %d task with %d. mask %lld\n", task->pid, current->pid, mask);
981969

982970
printk("Allocating new signal wait queue\n");
983971
sig_wait = kmalloc(sizeof(struct sig_wait_queue_struct), GFP_KERNEL);
984972
if (!sig_wait) {
985973
retval = -ENOMEM;
986974
goto done;
987975
}
988-
sig_wait->sigmask = sigmask;
976+
sig_wait->sigmask = mask;
989977
init_waitqueue_head(&sig_wait->wait_queue);
990978

991979
write_lock(&tasklist_lock);
992980
list_add(&sig_wait->list, &task->sig_wait_list);
993981
write_unlock(&tasklist_lock);
994982

995-
if (start_the_task) {
983+
if (mask & (1ULL << PROCTRACE_SYSTEM_CALLS)) {
984+
set_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
985+
}
986+
987+
if (mask & (1ULL << PROCTRACE_START_TASK)) {
996988
wake_up_process(task);
989+
// we don't need this flag anymore
990+
mask ^= 1ULL << PROCTRACE_START_TASK;
997991
}
998992

999993
prepare_to_wait(&sig_wait->wait_queue, &wait, TASK_INTERRUPTIBLE);
1000994
schedule();
1001995
finish_wait(&sig_wait->wait_queue, &wait);
1002996

997+
if (mask & (1ULL << PROCTRACE_SYSTEM_CALLS)) {
998+
clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
999+
}
1000+
10031001
write_lock(&tasklist_lock);
10041002
list_del(&sig_wait->list);
10051003
write_unlock(&tasklist_lock);
@@ -1010,34 +1008,36 @@ static int ctl_waitsignal(struct task_struct *task, int sigmask, int start_the_t
10101008
return retval;
10111009
}
10121010

1013-
static int ctl_get_sigmask(const char __user *buf, int count) {
1014-
int i, retval = 0;
1011+
static ssize_t wait_write(struct file *file, const char __user *buf,
1012+
size_t count, loff_t *ppos) {
1013+
unsigned long long mask = 0;
1014+
int i = 0;
1015+
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
10151016

1016-
for (i = 0; i < count; ++i) {
1017-
if (buf[i] == '1' || buf[i] == '0') {
1018-
retval = retval * 2 + (int)(buf[i]-'0');
1019-
} else if (buf[i] != ' ') {
1020-
break;
1021-
}
1017+
for (i = 0; i < count && i < 8; ++i) {
1018+
mask <<= 8;
1019+
mask |= buf[i];
10221020
}
10231021

1024-
return retval;
1025-
}
1022+
wait_waitsignal(task, mask);
10261023

1024+
return count;
1025+
}
10271026

1028-
static int ctl_wait(struct task_struct *task, int start_the_task) {
1029-
DEFINE_WAIT(wait);
1030-
1031-
printk("PROCTRACE waiting %d task with %d\n", task->pid, current->pid);
1032-
1033-
if (start_the_task) {
1034-
wake_up_process(task);
1035-
}
1027+
static const struct file_operations proc_wait_operations = {
1028+
.write= wait_write,
1029+
};
10361030

1037-
prepare_to_wait(&task->wq_for_stop, &wait, TASK_INTERRUPTIBLE);
1038-
schedule();
1039-
finish_wait(&task->wq_for_stop, &wait);
1031+
static int ctl_stop(struct task_struct *task)
1032+
{
1033+
printk("PROCTRACE stopping %d task with %d\n", task->pid, current->pid);
1034+
send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
1035+
return 0;
1036+
}
10401037

1038+
static int ctl_start(struct task_struct *task) {
1039+
printk("PROCTRACE continuing %d task with %d\n", task->pid, current->pid);
1040+
wake_up_process(task);
10411041
return 0;
10421042
}
10431043

@@ -1046,31 +1046,15 @@ static ssize_t ctl_write(struct file *file, const char __user *buf,
10461046
{
10471047
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
10481048

1049-
if (strncmp(buf, "waitsignal", 10) == 0) {
1050-
ctl_waitsignal(task, ctl_get_sigmask(buf + 11, count - 11), 0);
1051-
} else if (strncmp(buf, "startwaitsignal", 15) == 0) {
1052-
ctl_waitsignal(task, ctl_get_sigmask(buf + 16, count - 16), 1);
1053-
} else if (strncmp(buf, "waitsyscall", 9) == 0) {
1054-
set_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
1055-
ctl_waitsignal(task, 1 << SIGTRAP, 0);
1056-
clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
1057-
} else if (strncmp(buf, "startwaitsyscall", 9) == 0) {
1058-
set_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
1059-
ctl_waitsignal(task, 1 << SIGTRAP, 1);
1060-
clear_tsk_thread_flag(task, TIF_SYSCALL_TRACE);
1061-
} else if (strncmp(buf, "startwait", 9) == 0) {
1062-
ctl_wait(task, 1);
1063-
} else if (strncmp(buf, "stop", 4) == 0) {
1049+
if (strncmp(buf, "stop", 4) == 0) {
10641050
ctl_stop(task);
10651051
} else if (strncmp(buf, "start", 5) == 0) {
10661052
ctl_start(task);
1067-
} else if (strncmp(buf, "wait", 4) == 0) {
1068-
ctl_wait(task, 0);
10691053
} else if (strncmp(buf, "step", 4) == 0) {
10701054
if (unlikely(!arch_has_block_step()))
10711055
return -EIO;
10721056
user_enable_block_step(task);
1073-
ctl_waitsignal(task, 1 << SIGTRAP, 1);
1057+
wait_waitsignal(task, (1ULL << SIGTRAP) | (1ULL << PROCTRACE_START_TASK));
10741058
user_disable_single_step(task);
10751059
}
10761060

@@ -1081,6 +1065,7 @@ static const struct file_operations proc_ctl_operations = {
10811065
.write= ctl_write,
10821066
};
10831067

1068+
10841069
static ssize_t environ_read(struct file *file, char __user *buf,
10851070
size_t count, loff_t *ppos)
10861071
{
@@ -2929,6 +2914,7 @@ static const struct pid_entry tgid_base_stuff[] = {
29292914
#endif
29302915
REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
29312916
REG("ctl", S_IWUSR, proc_ctl_operations),
2917+
REG("wait", S_IWUSR, proc_wait_operations),
29322918
LNK("cwd", proc_cwd_link),
29332919
LNK("root", proc_root_link),
29342920
LNK("exe", proc_exe_link),

include/linux/init_task.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ 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-
.wq_for_stop = __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wq_for_stop),\
159158
.sig_wait_list = LIST_HEAD_INIT(tsk.sig_wait_list), \
160159
.real_parent = &tsk, \
161160
.parent = &tsk, \

include/linux/ptrace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
/* ptrace.h */
44
/* structs and defines to help the user use the ptrace system call. */
55

6+
/* stealing some space for proctrace */
7+
#define PROCTRACE_START_TASK 0
8+
#define PROCTRACE_SYSTEM_CALLS 33
9+
#define PROCTRACE_FORK 34
10+
#define PROCTRACE_VFORK 35
11+
#define PROCTRACE_CLONE 36
12+
#define PROCTRACE_EXEC 37
13+
#define PROCTRACE_VFORK_DONE 38
14+
#define PROCTRACE_EXIT 39
15+
16+
617
/* has the defines to get at the registers. */
718

819
#define PTRACE_TRACEME 0

include/linux/sched.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,7 @@ enum perf_event_task_context {
12181218
};
12191219

12201220
struct sig_wait_queue_struct {
1221-
int sigmask;
1221+
unsigned long long sigmask;
12221222
/* actual wait queue -> can have only one element in it */
12231223
wait_queue_head_t wait_queue;
12241224
/* all other signal queues for this task */
@@ -1343,8 +1343,6 @@ struct task_struct {
13431343
struct list_head ptraced;
13441344
struct list_head ptrace_entry;
13451345

1346-
/* Debuggers waiting for child to stop or exit */
1347-
wait_queue_head_t wq_for_stop;
13481346
/* Debuggers waiting for child to get a signal or exit */
13491347
struct list_head sig_wait_list;
13501348

include/linux/tracehook.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
7272
}
7373
}
7474
if (!list_empty(&current->sig_wait_list)) {
75-
proctrace_notify(SIGTRAP);
75+
proctrace_notify(PROCTRACE_SYSTEM_CALLS);
7676
}
7777
}
7878

kernel/fork.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
13031303
p->exit_state = 0;
13041304

13051305
/* Initialize proctrace data structures */
1306-
init_waitqueue_head(&p->wq_for_stop);
13071306
INIT_LIST_HEAD(&p->sig_wait_list);
13081307

13091308
/*

kernel/signal.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
15901590
bool do_notify_parent(struct task_struct *tsk, int sig)
15911591
{
15921592
struct list_head *p;
1593+
struct sig_wait_queue_struct *sig_wait;
15931594
struct siginfo info;
15941595
unsigned long flags;
15951596
struct sighand_struct *psig;
@@ -1666,12 +1667,10 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
16661667
__wake_up_parent(tsk, tsk->parent);
16671668

16681669
/* also notify all the proctraces */
1669-
wake_up(&tsk->wq_for_stop);
16701670
list_for_each(p, &tsk->sig_wait_list) {
16711671
printk("PROCTRACE budim frajera jer je child umro\n");
1672-
wake_up(&list_entry(
1673-
p, struct sig_wait_queue_struct,
1674-
list)->wait_queue);
1672+
sig_wait = list_entry(p, struct sig_wait_queue_struct, list);
1673+
wake_up(&sig_wait->wait_queue);
16751674
}
16761675

16771676
spin_unlock_irqrestore(&psig->siglock, flags);
@@ -1699,6 +1698,8 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
16991698
unsigned long flags;
17001699
struct task_struct *parent;
17011700
struct sighand_struct *sighand;
1701+
struct sig_wait_queue_struct *sig_wait;
1702+
struct list_head *p;
17021703

17031704
if (for_ptracer) {
17041705
parent = tsk->parent;
@@ -1745,8 +1746,15 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
17451746
*/
17461747
__wake_up_parent(tsk, parent);
17471748
if (why == CLD_STOPPED) {
1749+
printk("PROCTRACE child je stao\n");
17481750
/* wake up all the proctraces waiting for stop */
1749-
wake_up(&tsk->wq_for_stop);
1751+
list_for_each(p, &tsk->sig_wait_list) {
1752+
sig_wait = list_entry(p, struct sig_wait_queue_struct, list);
1753+
if (sig_wait->sigmask == 0) {
1754+
printk("PROCTRACE budim frajera jer je child stao\n");
1755+
wake_up(&sig_wait->wait_queue);
1756+
}
1757+
}
17501758
}
17511759
spin_unlock_irqrestore(&sighand->siglock, flags);
17521760
}
@@ -2117,7 +2125,7 @@ static int proctrace_signal(int signr) {
21172125
printk("PROCTRACE provjeravam jedan proces\n");
21182126
sig_wait = list_entry(p, struct sig_wait_queue_struct, list);
21192127

2120-
if (sig_wait->sigmask & (1 << signr)) {
2128+
if (sig_wait->sigmask & (1ULL << signr)) {
21212129
printk("PROCTRACE Sigmask je dobar, budim debuggera\n");
21222130
/* ignore the signal */
21232131
retval = 0;

0 commit comments

Comments
 (0)