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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 11 Mar 2021 09:31:59 +0800
From:   kernel test robot <lkp@...el.com>
To:     Jim Newsome <jnewsome@...project.org>,
        Oleg Nesterov <oleg@...hat.com>
Cc:     kbuild-all@...ts.01.org, linux-kernel@...r.kernel.org,
        Jim Newsome <jnewsome@...project.org>
Subject: Re: [PATCH] ptrace: Allow other threads to access tracee

Hi Jim,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linux/master]
[also build test WARNING on linus/master v5.12-rc2 next-20210310]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jim-Newsome/ptrace-Allow-other-threads-to-access-tracee/20210311-050039
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 144c79ef33536b4ecb4951e07dbc1f2b7fa99d32
config: x86_64-randconfig-s021-20210309 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-262-g5e674421-dirty
        # https://github.com/0day-ci/linux/commit/874466f21257b7eb31b17d2bdb19da3f365436d7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jim-Newsome/ptrace-Allow-other-threads-to-access-tracee/20210311-050039
        git checkout 874466f21257b7eb31b17d2bdb19da3f365436d7
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@...el.com>


"sparse warnings: (new ones prefixed by >>)"
>> kernel/ptrace.c:53:44: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *p2 @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/ptrace.c:53:44: sparse:     expected struct task_struct *p2
   kernel/ptrace.c:53:44: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:72:23: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *parent @@     got struct task_struct *new_parent @@
   kernel/ptrace.c:72:23: sparse:     expected struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:72:23: sparse:     got struct task_struct *new_parent
   kernel/ptrace.c:73:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct cred const [noderef] __rcu *ptracer_cred @@     got struct cred const * @@
   kernel/ptrace.c:73:29: sparse:     expected struct cred const [noderef] __rcu *ptracer_cred
   kernel/ptrace.c:73:29: sparse:     got struct cred const *
   kernel/ptrace.c:127:18: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct cred const *old_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   kernel/ptrace.c:127:18: sparse:     expected struct cred const *old_cred
   kernel/ptrace.c:127:18: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/ptrace.c:131:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:131:25: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:131:25: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:169:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:169:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:169:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:181:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:181:28: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:181:28: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:186:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:186:30: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:186:30: sparse:     got struct spinlock [noderef] __rcu *
>> kernel/ptrace.c:196:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/ptrace.c:196:9: sparse:     expected struct task_struct *p1
   kernel/ptrace.c:196:9: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:202:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:202:28: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:202:28: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:209:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:209:30: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:209:30: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:241:53: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/ptrace.c:241:53: sparse:     expected struct task_struct *p1
   kernel/ptrace.c:241:53: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:415:24: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:415:24: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:415:24: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:438:26: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:438:26: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:438:26: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:474:54: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/ptrace.c:474:54: sparse:     expected struct task_struct *parent
   kernel/ptrace.c:474:54: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:482:53: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/ptrace.c:482:53: sparse:     expected struct task_struct *new_parent
   kernel/ptrace.c:482:53: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/ptrace.c:530:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/ptrace.c:530:41: sparse:     expected struct task_struct *p1
   kernel/ptrace.c:530:41: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/ptrace.c:532:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sigh @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/ptrace.c:532:50: sparse:     expected struct sighand_struct *sigh
   kernel/ptrace.c:532:50: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/ptrace.c:734:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:734:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:734:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:742:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:742:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:742:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:847:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:847:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:847:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:851:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:851:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:851:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1081:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:1081:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:1081:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1083:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:1083:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:1083:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:480:38: sparse: sparse: dereference of noderef expression
   kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
   include/linux/sched/signal.h:708:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:708:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:708:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:681:9: sparse: sparse: context imbalance in 'ptrace_getsiginfo' - different lock contexts for basic block
   include/linux/sched/signal.h:708:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:708:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:708:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:697:9: sparse: sparse: context imbalance in 'ptrace_setsiginfo' - different lock contexts for basic block
   kernel/ptrace.c:853:9: sparse: sparse: context imbalance in 'ptrace_resume' - different lock contexts for basic block
   include/linux/sched/signal.h:708:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:708:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:708:37: sparse:     got struct spinlock [noderef] __rcu *
   include/linux/sched/signal.h:708:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:708:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:708:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1229:9: sparse: sparse: context imbalance in 'ptrace_request' - different lock contexts for basic block

vim +53 kernel/ptrace.c

    36	
    37	/*
    38	 * Access another process' address space via ptrace.
    39	 * Source/target buffer must be kernel space,
    40	 * Do not walk the page table directly, use get_user_pages
    41	 */
    42	int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
    43			     void *buf, int len, unsigned int gup_flags)
    44	{
    45		struct mm_struct *mm;
    46		int ret;
    47	
    48		mm = get_task_mm(tsk);
    49		if (!mm)
    50			return 0;
    51	
    52		if (!tsk->ptrace ||
  > 53		    !same_thread_group(current, tsk->parent) ||
    54		    ((get_dumpable(mm) != SUID_DUMP_USER) &&
    55		     !ptracer_capable(tsk, mm->user_ns))) {
    56			mmput(mm);
    57			return 0;
    58		}
    59	
    60		ret = __access_remote_vm(mm, addr, buf, len, gup_flags);
    61		mmput(mm);
    62	
    63		return ret;
    64	}
    65	
    66	
    67	void __ptrace_link(struct task_struct *child, struct task_struct *new_parent,
    68			   const struct cred *ptracer_cred)
    69	{
    70		BUG_ON(!list_empty(&child->ptrace_entry));
    71		list_add(&child->ptrace_entry, &new_parent->ptraced);
    72		child->parent = new_parent;
    73		child->ptracer_cred = get_cred(ptracer_cred);
    74	}
    75	
    76	/*
    77	 * ptrace a task: make the debugger its new parent and
    78	 * move it to the ptrace list.
    79	 *
    80	 * Must be called with the tasklist lock write-held.
    81	 */
    82	static void ptrace_link(struct task_struct *child, struct task_struct *new_parent)
    83	{
    84		__ptrace_link(child, new_parent, current_cred());
    85	}
    86	
    87	/**
    88	 * __ptrace_unlink - unlink ptracee and restore its execution state
    89	 * @child: ptracee to be unlinked
    90	 *
    91	 * Remove @child from the ptrace list, move it back to the original parent,
    92	 * and restore the execution state so that it conforms to the group stop
    93	 * state.
    94	 *
    95	 * Unlinking can happen via two paths - explicit PTRACE_DETACH or ptracer
    96	 * exiting.  For PTRACE_DETACH, unless the ptracee has been killed between
    97	 * ptrace_check_attach() and here, it's guaranteed to be in TASK_TRACED.
    98	 * If the ptracer is exiting, the ptracee can be in any state.
    99	 *
   100	 * After detach, the ptracee should be in a state which conforms to the
   101	 * group stop.  If the group is stopped or in the process of stopping, the
   102	 * ptracee should be put into TASK_STOPPED; otherwise, it should be woken
   103	 * up from TASK_TRACED.
   104	 *
   105	 * If the ptracee is in TASK_TRACED and needs to be moved to TASK_STOPPED,
   106	 * it goes through TRACED -> RUNNING -> STOPPED transition which is similar
   107	 * to but in the opposite direction of what happens while attaching to a
   108	 * stopped task.  However, in this direction, the intermediate RUNNING
   109	 * state is not hidden even from the current ptracer and if it immediately
   110	 * re-attaches and performs a WNOHANG wait(2), it may fail.
   111	 *
   112	 * CONTEXT:
   113	 * write_lock_irq(tasklist_lock)
   114	 */
   115	void __ptrace_unlink(struct task_struct *child)
   116	{
   117		const struct cred *old_cred;
   118		BUG_ON(!child->ptrace);
   119	
   120		clear_task_syscall_work(child, SYSCALL_TRACE);
   121	#if defined(CONFIG_GENERIC_ENTRY) || defined(TIF_SYSCALL_EMU)
   122		clear_task_syscall_work(child, SYSCALL_EMU);
   123	#endif
   124	
   125		child->parent = child->real_parent;
   126		list_del_init(&child->ptrace_entry);
   127		old_cred = child->ptracer_cred;
   128		child->ptracer_cred = NULL;
   129		put_cred(old_cred);
   130	
   131		spin_lock(&child->sighand->siglock);
   132		child->ptrace = 0;
   133		/*
   134		 * Clear all pending traps and TRAPPING.  TRAPPING should be
   135		 * cleared regardless of JOBCTL_STOP_PENDING.  Do it explicitly.
   136		 */
   137		task_clear_jobctl_pending(child, JOBCTL_TRAP_MASK);
   138		task_clear_jobctl_trapping(child);
   139	
   140		/*
   141		 * Reinstate JOBCTL_STOP_PENDING if group stop is in effect and
   142		 * @child isn't dead.
   143		 */
   144		if (!(child->flags & PF_EXITING) &&
   145		    (child->signal->flags & SIGNAL_STOP_STOPPED ||
   146		     child->signal->group_stop_count)) {
   147			child->jobctl |= JOBCTL_STOP_PENDING;
   148	
   149			/*
   150			 * This is only possible if this thread was cloned by the
   151			 * traced task running in the stopped group, set the signal
   152			 * for the future reports.
   153			 * FIXME: we should change ptrace_init_task() to handle this
   154			 * case.
   155			 */
   156			if (!(child->jobctl & JOBCTL_STOP_SIGMASK))
   157				child->jobctl |= SIGSTOP;
   158		}
   159	
   160		/*
   161		 * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick
   162		 * @child in the butt.  Note that @resume should be used iff @child
   163		 * is in TASK_TRACED; otherwise, we might unduly disrupt
   164		 * TASK_KILLABLE sleeps.
   165		 */
   166		if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child))
   167			ptrace_signal_wake_up(child, true);
   168	
   169		spin_unlock(&child->sighand->siglock);
   170	}
   171	
   172	/* Ensure that nothing can wake it up, even SIGKILL */
   173	static bool ptrace_freeze_traced(struct task_struct *task)
   174	{
   175		bool ret = false;
   176	
   177		/* Lockless, nobody but us can set this flag */
   178		if (task->jobctl & JOBCTL_LISTENING)
   179			return ret;
   180	
   181		spin_lock_irq(&task->sighand->siglock);
   182		if (task_is_traced(task) && !__fatal_signal_pending(task)) {
   183			task->state = __TASK_TRACED;
   184			ret = true;
   185		}
   186		spin_unlock_irq(&task->sighand->siglock);
   187	
   188		return ret;
   189	}
   190	
   191	static void ptrace_unfreeze_traced(struct task_struct *task)
   192	{
   193		if (task->state != __TASK_TRACED)
   194			return;
   195	
 > 196		WARN_ON(!task->ptrace || !same_thread_group(task->parent, current));
   197	
   198		/*
   199		 * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely.
   200		 * Recheck state under the lock to close this race.
   201		 */
   202		spin_lock_irq(&task->sighand->siglock);
   203		if (task->state == __TASK_TRACED) {
   204			if (__fatal_signal_pending(task))
   205				wake_up_state(task, __TASK_TRACED);
   206			else
   207				task->state = TASK_TRACED;
   208		}
   209		spin_unlock_irq(&task->sighand->siglock);
   210	}
   211	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Download attachment ".config.gz" of type "application/gzip" (30044 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ