1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
From 619aaa241ec852ea44aa3edbd59aa9c08b8adc9f Mon Sep 17 00:00:00 2001
From: xietangxin <xietangxin@huawei.com>
Date: Wed, 22 Nov 2023 14:26:13 +0800
Subject: [PATCH] bugfix: fix signal monitor err
---
module/signo_catch.c | 68 ++++++++++++++++-----------
module/signo_catch.h | 6 +++
src/sys_event.c | 1 +
3 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/module/signo_catch.c b/module/signo_catch.c
index 5273f29..c038e16 100644
--- a/module/signo_catch.c
+++ b/module/signo_catch.c
@@ -12,6 +12,7 @@
#include <linux/netlink.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
+#include <linux/kprobes.h>
#include "sysmonitor_main.h"
@@ -28,6 +29,10 @@ static ulong g_qemu_buf_seq; /* index for reader */
static qemu_signo_msg g_qemu_buf[SIG_BUFSIZE];
struct proc_dir_entry *g_proc_qemu;
+static struct kprobe kp = {
+ .symbol_name = "do_send_sig_info"
+};
+
static ssize_t qemu_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
int error, index;
@@ -91,7 +96,6 @@ static const struct proc_ops g_proc_qemu_operations = {
};
#endif
-#ifdef CONFIG_EULEROS_SYSMONITOR_SIGNAL
/* Here introduce euler_get_mm_exe_file and euler_get_task_exe_file
* to solve the build and insmod error.
*/
@@ -132,16 +136,16 @@ static struct file *euler_get_task_exe_file(struct task_struct *task)
static int save_exe_info(char *exe, int exe_size, struct task_struct *task)
{
struct file *exe_file = NULL;
- int ret;
+ void *ret;
exe_file = euler_get_task_exe_file(task);
if (exe_file != NULL) {
ret = memcpy(exe,
exe_file->f_path.dentry->d_name.name,
exe_file->f_path.dentry->d_name.len);
- if (ret != 0) {
+ if (ret == NULL) {
fput(exe_file);
- return ret;
+ return -1;
}
fput(exe_file);
}
@@ -200,8 +204,6 @@ static int save_msg_info(ce_signo_msg *msg, const send_sig_info_data_t *notifier
static int save_qemu_msg_info(qemu_signo_msg *qemu_msg, const send_sig_info_data_t *notifier_call_data)
{
- int ret;
-
(void)memset(qemu_msg, 0, sizeof(qemu_signo_msg));
qemu_msg->send_pid = current->pid;
(void)memcpy(qemu_msg->send_comm, current->comm, TASK_COMM_LEN);
@@ -213,18 +215,17 @@ static int save_qemu_msg_info(qemu_signo_msg *qemu_msg, const send_sig_info_data
return 0;
}
-static int do_store_sig_info(struct notifier_block *self, unsigned long val, void *data)
+static int do_store_sig_info(send_sig_info_data_t *data)
{
- send_sig_info_data_t *notifier_call_data = (send_sig_info_data_t *)data;
ce_signo_msg msg;
ulong index;
qemu_signo_msg *qemu_msg = NULL;
unsigned long sigcatchmask = get_sigcatchmask();
int ret;
- if ((notifier_call_data->sig <= SIGNAL_COUNT) &&
- (sigcatchmask & (1ul << (unsigned int)(notifier_call_data->sig - 1)))) {
- ret = save_msg_info(&msg, notifier_call_data);
+ if ((data->sig <= SIGNAL_COUNT) &&
+ (sigcatchmask & (1ul << (unsigned int)(data->sig - 1)))) {
+ ret = save_msg_info(&msg, data);
if (ret != 0) {
goto out;
}
@@ -233,12 +234,12 @@ static int do_store_sig_info(struct notifier_block *self, unsigned long val, voi
}
#ifdef QEMU_SIG
- if ((notifier_call_data->sig == SIGKILL) &&
- !strcmp(notifier_call_data->p->comm, "qemu-kvm")) {
+ if ((data->sig == SIGKILL) &&
+ !strcmp(data->p->comm, "qemu-kvm")) {
index = g_qemu_buf_seq & SIG_BUFMASK;
qemu_msg = g_qemu_buf + index;
- ret = save_qemu_msg_info(qemu_msg, notifier_call_data);
+ ret = save_qemu_msg_info(qemu_msg, data);
if (ret) {
goto out;
}
@@ -251,15 +252,30 @@ static int do_store_sig_info(struct notifier_block *self, unsigned long val, voi
}
#endif
out:
- return NOTIFY_DONE;
+ return 0;
}
-static struct notifier_block g_signo_catch_nb = {
- .notifier_call = do_store_sig_info,
- .priority = NOTIFY_CALL_PRIORITY,
-};
+static int pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+#ifdef CONFIG_ARM64
+ send_sig_info_data_t data;
+ data.sig = regs->regs[0];
+ data.info = (struct kernel_siginfo *)((unsigned long *)regs->regs[1]);
+ data.p = (struct task_struct *)((unsigned long *)regs->regs[2]);
+ do_store_sig_info(&data);
#endif
+#ifdef CONFIG_X86_64
+ send_sig_info_data_t data;
+ data.sig = regs->di;
+ data.info = (struct kernel_siginfo *)((unsigned long *)regs->si);
+ data.p = (struct task_struct *)((unsigned long *)regs->dx);
+ do_store_sig_info(&data);
+#endif
+ return 0;
+}
+
+
void signo_catch_init(void)
{
#ifdef QEMU_SIG
@@ -268,22 +284,20 @@ void signo_catch_init(void)
printk(KERN_ERR "signo_catch: create /proc/sig_catch failed.\n");
}
#endif
-#ifdef CONFIG_EULEROS_SYSMONITOR_SIGNAL
- (void)register_signo_catch_notifier(&g_signo_catch_nb);
-#endif
- printk(KERN_INFO "signo_catch: Planted send_sig_info_notifier_list register\n");
+ kp.pre_handler = pre_handler;
+ register_kprobe(&kp);
+
+ printk(KERN_INFO "signo_catch: register signal kprobe\n");
}
void signo_catch_exit(void)
{
-#ifdef CONFIG_EULEROS_SYSMONITOR_SIGNAL
- (void)unregister_signo_catch_notifier(&g_signo_catch_nb);
-#endif
+ unregister_kprobe(&kp);
#ifdef QEMU_SIG
if (g_proc_qemu != NULL) {
proc_remove(g_proc_qemu);
}
#endif
- printk(KERN_INFO "signo_catch: send_sig_info_notifier_list unregistered\n");
+ printk(KERN_INFO "signo_catch: unregister signal kprobe\n");
}
diff --git a/module/signo_catch.h b/module/signo_catch.h
index 0c2b9f7..b2ce684 100644
--- a/module/signo_catch.h
+++ b/module/signo_catch.h
@@ -38,6 +38,12 @@ typedef struct __signo_msg {
char recv_comm[TASK_COMM_LEN];
} qemu_signo_msg;
+typedef struct send_sig_info_data {
+ int sig;
+ struct kernel_siginfo *info;
+ struct task_struct *p;
+} send_sig_info_data_t;
+
void signo_catch_init(void);
void signo_catch_exit(void);
diff --git a/src/sys_event.c b/src/sys_event.c
index 61701ec..9674b98 100644
--- a/src/sys_event.c
+++ b/src/sys_event.c
@@ -681,6 +681,7 @@ static int handle_signo_msg(const sysmonitor_event_msg *event_msg)
log_printf(LOG_ERR, "sig_monitor_start: snprintf_s alarm_msg failed.");
return -1;
}
+ log_printf(LOG_INFO, "%s", alarm_msg);
}
return 0;
--
2.20.1.windows.1
|