lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20240920000933.185090-2-anjali.k.kulkarni@oracle.com>
Date: Thu, 19 Sep 2024 17:09:32 -0700
From: Anjali Kulkarni <anjali.k.kulkarni@...cle.com>
To: davem@...emloft.net, Liam.Howlett@...cle.com
Cc: edumazet@...gle.com, kuba@...nel.org, pabeni@...hat.com, oleg@...hat.com,
        akpm@...ux-foundation.org, axboe@...nel.dk, brauner@...nel.org,
        mhocko@...e.com, alexjlzheng@...cent.com, willy@...radead.org,
        michael.christie@...cle.com, linux-kernel@...r.kernel.org,
        netdev@...r.kernel.org, shuah@...nel.org,
        linux-kselftest@...r.kernel.org, anjali.k.kulkarni@...cle.com,
        peili.io@...cle.com
Subject: [PATCH net-next 1/2] connector/cn_proc: Handle threads for proc connector

Add a new type PROC_CN_MCAST_NOTIFY to proc connector API, which allows a
thread to notify the kernel that it has exited abnormally. Thread can also
send the exit status code it wants returned in the notification with it.
Exiting thread can call this either when it wants to call pthread_exit()
with non-zero value or from signal handler.

Once kernel receives this, it saves this exit status in the thread's
exit_code field of task_struct. This field is then checked when the thread
actually exits, and if non-zero, it is copied to the notification to be
sent.

Signed-off-by: Anjali Kulkarni <anjali.k.kulkarni@...cle.com>
---
 drivers/connector/cn_proc.c  | 11 +++++++++--
 include/linux/cn_proc.h      |  5 +++--
 include/uapi/linux/cn_proc.h |  4 +++-
 kernel/exit.c                |  5 ++++-
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 44b19e696176..4c38b9bf4f2f 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -320,7 +320,7 @@ void proc_coredump_connector(struct task_struct *task)
 	send_msg(msg);
 }
 
-void proc_exit_connector(struct task_struct *task)
+void proc_exit_connector(struct task_struct *task, __u32 uexit_code)
 {
 	struct cn_msg *msg;
 	struct proc_event *ev;
@@ -337,7 +337,10 @@ void proc_exit_connector(struct task_struct *task)
 	ev->what = PROC_EVENT_EXIT;
 	ev->event_data.exit.process_pid = task->pid;
 	ev->event_data.exit.process_tgid = task->tgid;
-	ev->event_data.exit.exit_code = task->exit_code;
+	if (task->exit_code == 0)
+		ev->event_data.exit.exit_code = uexit_code;
+	else
+		ev->event_data.exit.exit_code = task->exit_code;
 	ev->event_data.exit.exit_signal = task->exit_signal;
 
 	rcu_read_lock();
@@ -413,6 +416,10 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
 	if (msg->len == sizeof(*pinput)) {
 		pinput = (struct proc_input *)msg->data;
 		mc_op = pinput->mcast_op;
+		if (mc_op == PROC_CN_MCAST_NOTIFY) {
+			current->exit_code = pinput->uexit_code;
+			return;
+		}
 		ev_type = pinput->event_type;
 	} else if (msg->len == sizeof(mc_op)) {
 		mc_op = *((enum proc_cn_mcast_op *)msg->data);
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
index 1d5b02a96c46..fc1d75897cc7 100644
--- a/include/linux/cn_proc.h
+++ b/include/linux/cn_proc.h
@@ -27,7 +27,7 @@ void proc_sid_connector(struct task_struct *task);
 void proc_ptrace_connector(struct task_struct *task, int which_id);
 void proc_comm_connector(struct task_struct *task);
 void proc_coredump_connector(struct task_struct *task);
-void proc_exit_connector(struct task_struct *task);
+void proc_exit_connector(struct task_struct *task, __u32 uexit_code);
 #else
 static inline void proc_fork_connector(struct task_struct *task)
 {}
@@ -52,7 +52,8 @@ static inline void proc_ptrace_connector(struct task_struct *task,
 static inline void proc_coredump_connector(struct task_struct *task)
 {}
 
-static inline void proc_exit_connector(struct task_struct *task)
+static inline void proc_exit_connector(struct task_struct *task,
+					__u32 uexit_code)
 {}
 #endif	/* CONFIG_PROC_EVENTS */
 #endif	/* CN_PROC_H */
diff --git a/include/uapi/linux/cn_proc.h b/include/uapi/linux/cn_proc.h
index 18e3745b86cd..2b12a24e4651 100644
--- a/include/uapi/linux/cn_proc.h
+++ b/include/uapi/linux/cn_proc.h
@@ -27,7 +27,8 @@
  */
 enum proc_cn_mcast_op {
 	PROC_CN_MCAST_LISTEN = 1,
-	PROC_CN_MCAST_IGNORE = 2
+	PROC_CN_MCAST_IGNORE = 2,
+	PROC_CN_MCAST_NOTIFY = 3
 };
 
 #define PROC_EVENT_ALL (PROC_EVENT_FORK | PROC_EVENT_EXEC | PROC_EVENT_UID |  \
@@ -65,6 +66,7 @@ enum proc_cn_event {
 struct proc_input {
 	enum proc_cn_mcast_op mcast_op;
 	enum proc_cn_event event_type;
+	__u32 uexit_code;
 };
 
 static inline enum proc_cn_event valid_event(enum proc_cn_event ev_type)
diff --git a/kernel/exit.c b/kernel/exit.c
index 7430852a8571..e2698ebe59ea 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -821,6 +821,7 @@ void __noreturn do_exit(long code)
 {
 	struct task_struct *tsk = current;
 	int group_dead;
+	__u32 uexit_code;
 
 	WARN_ON(irqs_disabled());
 
@@ -863,6 +864,8 @@ void __noreturn do_exit(long code)
 		tty_audit_exit();
 	audit_free(tsk);
 
+	uexit_code = tsk->exit_code;
+
 	tsk->exit_code = code;
 	taskstats_exit(tsk, group_dead);
 
@@ -900,7 +903,7 @@ void __noreturn do_exit(long code)
 
 	exit_tasks_rcu_start();
 	exit_notify(tsk, group_dead);
-	proc_exit_connector(tsk);
+	proc_exit_connector(tsk, uexit_code);
 	mpol_put_task_policy(tsk);
 #ifdef CONFIG_FUTEX
 	if (unlikely(current->pi_state_cache))
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ