Unverified Commit 5e6caa2c authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6070 Fix CVE-2024-26686

Merge Pull Request from: @ci-robot 
 
PR sync from: Zhao Wenhui <zhaowenhui8@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/BZEWUKEAG7JVGFMWGMIFCCTGX7M34BMJ/ 
Fix CVE-2024-26686

Eric W. Biederman (1):
  exit: Use the correct exit_code in /proc/<pid>/stat

Oleg Nesterov (3):
  fs/proc: do_task_stat: use __for_each_thread()
  fs/proc: do_task_stat: move thread_group_cputime_adjusted() outside of
    lock_task_sighand()
  fs/proc: do_task_stat: use sig->stats_lock to gather the
    threads/children stats


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/I9E2EL 
 
Link:https://gitee.com/openeuler/kernel/pulls/6070

 

Reviewed-by: default avatarLiu YongQiang <liuyongqiang13@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents d9998017 4f873051
Loading
Loading
Loading
Loading
+41 −28
Original line number Diff line number Diff line
@@ -443,12 +443,13 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
	int permitted;
	struct mm_struct *mm;
	unsigned long long start_time;
	unsigned long cmin_flt = 0, cmaj_flt = 0;
	unsigned long  min_flt = 0,  maj_flt = 0;
	u64 cutime, cstime, utime, stime;
	u64 cgtime, gtime;
	unsigned long cmin_flt, cmaj_flt, min_flt, maj_flt;
	u64 cutime, cstime, cgtime, utime, stime, gtime;
	unsigned long rsslim = 0;
	unsigned long flags;
	int exit_code = task->exit_code;
	struct signal_struct *sig = task->signal;
	unsigned int seq = 1;

	state = *get_task_state(task);
	vsize = eip = esp = 0;
@@ -476,12 +477,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

	sigemptyset(&sigign);
	sigemptyset(&sigcatch);
	cutime = cstime = utime = stime = 0;
	cgtime = gtime = 0;

	if (lock_task_sighand(task, &flags)) {
		struct signal_struct *sig = task->signal;

		if (sig->tty) {
			struct pid *pgrp = tty_get_pgrp(sig->tty);
			tty_pgrp = pid_nr_ns(pgrp, ns);
@@ -492,26 +489,11 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
		num_threads = get_nr_threads(task);
		collect_sigign_sigcatch(task, &sigign, &sigcatch);

		cmin_flt = sig->cmin_flt;
		cmaj_flt = sig->cmaj_flt;
		cutime = sig->cutime;
		cstime = sig->cstime;
		cgtime = sig->cgtime;
		rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);

		/* add up live thread stats at the group level */
		if (whole) {
			struct task_struct *t = task;
			do {
				min_flt += t->min_flt;
				maj_flt += t->maj_flt;
				gtime += task_gtime(t);
			} while_each_thread(task, t);

			min_flt += sig->min_flt;
			maj_flt += sig->maj_flt;
			thread_group_cputime_adjusted(task, &utime, &stime);
			gtime += sig->gtime;
			if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED))
				exit_code = sig->group_exit_code;
		}

		sid = task_session_nr_ns(task, ns);
@@ -523,10 +505,41 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

	if (permitted && (!whole || num_threads < 2))
		wchan = get_wchan(task);
	if (!whole) {

	do {
		seq++; /* 2 on the 1st/lockless path, otherwise odd */
		flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);

		cmin_flt = sig->cmin_flt;
		cmaj_flt = sig->cmaj_flt;
		cutime = sig->cutime;
		cstime = sig->cstime;
		cgtime = sig->cgtime;

		if (whole) {
			struct task_struct *t;

			min_flt = sig->min_flt;
			maj_flt = sig->maj_flt;
			gtime = sig->gtime;

			rcu_read_lock();
			__for_each_thread(sig, t) {
				min_flt += t->min_flt;
				maj_flt += t->maj_flt;
				gtime += task_gtime(t);
			}
			rcu_read_unlock();
		}
	} while (need_seqretry(&sig->stats_lock, seq));
	done_seqretry_irqrestore(&sig->stats_lock, seq, flags);

	if (whole) {
		thread_group_cputime_adjusted(task, &utime, &stime);
	} else {
		task_cputime_adjusted(task, &utime, &stime);
		min_flt = task->min_flt;
		maj_flt = task->maj_flt;
		task_cputime_adjusted(task, &utime, &stime);
		gtime = task_gtime(task);
	}

@@ -613,7 +626,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
		seq_puts(m, " 0 0 0 0 0 0 0");

	if (permitted)
		seq_put_decimal_ll(m, " ", task->exit_code);
		seq_put_decimal_ll(m, " ", exit_code);
	else
		seq_puts(m, " 0");