All of lore.kernel.org
 help / color / mirror / Atom feed
From: Josh Poimboeuf <jpoimboe@redhat.com>
To: Petr Mladek <pmladek@suse.com>
Cc: Jessica Yu <jeyu@redhat.com>, Jiri Kosina <jikos@kernel.org>,
	Miroslav Benes <mbenes@suse.cz>,
	linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
	Michael Ellerman <mpe@ellerman.id.au>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	x86@kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-s390@vger.kernel.org, Vojtech Pavlik <vojtech@suse.com>,
	Jiri Slaby <jslaby@suse.cz>,
	Chris J Arges <chris.j.arges@canonical.com>,
	Andy Lutomirski <luto@kernel.org>, Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>,
	Balbir Singh <bsingharora@gmail.com>
Subject: Re: [PATCH v4 01/15] stacktrace/x86: add function for detecting reliable stack traces
Date: Thu, 26 Jan 2017 11:57:44 -0600	[thread overview]
Message-ID: <20170126175744.gv3ttlg52axuq57c@treble> (raw)
In-Reply-To: <20170126135603.GD27517@pathway.suse.cz>

On Thu, Jan 26, 2017 at 02:56:03PM +0100, Petr Mladek wrote:
> On Thu 2017-01-19 09:46:09, Josh Poimboeuf wrote:
> > For live patching and possibly other use cases, a stack trace is only
> > useful if it can be assured that it's completely reliable.  Add a new
> > save_stack_trace_tsk_reliable() function to achieve that.
> 
> > diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
> > index 0653788..fc36842 100644
> > --- a/arch/x86/kernel/stacktrace.c
> > +++ b/arch/x86/kernel/stacktrace.c
> > @@ -74,6 +74,90 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
> >  }
> >  EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
> >  
> > +#ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
> > +static int __save_stack_trace_reliable(struct stack_trace *trace,
> > +				       struct task_struct *task)
> > +{
> > +	struct unwind_state state;
> > +	struct pt_regs *regs;
> > +	unsigned long addr;
> > +
> > +	for (unwind_start(&state, task, NULL, NULL); !unwind_done(&state);
> > +	     unwind_next_frame(&state)) {
> > +
> > +		regs = unwind_get_entry_regs(&state);
> > +		if (regs) {
> > +			/*
> > +			 * Kernel mode registers on the stack indicate an
> > +			 * in-kernel interrupt or exception (e.g., preemption
> > +			 * or a page fault), which can make frame pointers
> > +			 * unreliable.
> > +			 */
> > +			if (!user_mode(regs))
> > +				return -1;
> > +
> > +			/*
> > +			 * The last frame contains the user mode syscall
> > +			 * pt_regs.  Skip it and finish the unwind.
> > +			 */
> > +			unwind_next_frame(&state);
> > +			if (WARN_ON_ONCE(!unwind_done(&state))) {
> > +				show_stack(task, NULL);
> 
> We should make sure that show_stack() is called only once as well.
> Otherwise, it would fill logbuffer with random stacktraces without
> any context. It might easily cause flood of messages and the first
> useful one might get lost in the ring buffer.

Agreed.

> > +				return -1;
> > +			}
> > +			break;
> > +		}
> > +
> > +		addr = unwind_get_return_address(&state);
> > +
> > +		/*
> > +		 * A NULL or invalid return address probably means there's some
> > +		 * generated code which __kernel_text_address() doesn't know
> > +		 * about.
> > +		 */
> > +		if (WARN_ON_ONCE(!addr)) {
> > +			show_stack(task, NULL);
> 
> Same here.
> 
> > +			return -1;
> > +		}
> > +
> > +		if (save_stack_address(trace, addr, false))
> > +			return -1;
> > +	}
> > +
> > +	/* Check for stack corruption */
> > +	if (WARN_ON_ONCE(unwind_error(&state))) {
> > +		show_stack(task, NULL);
> 
> And here.
> 
> > +		return -1;
> > +	}
> > +
> > +	if (trace->nr_entries < trace->max_entries)
> > +		trace->entries[trace->nr_entries++] = ULONG_MAX;
> > +
> > +	return 0;
> > +}
> > +
> > +/*
> > + * This function returns an error if it detects any unreliable features of the
> > + * stack.  Otherwise it guarantees that the stack trace is reliable.
> > + *
> > + * If the task is not 'current', the caller *must* ensure the task is inactive.
> > + */
> > +int save_stack_trace_tsk_reliable(struct task_struct *tsk,
> > +				  struct stack_trace *trace)
> > +{
> > +	int ret;
> > +
> > +	if (!try_get_task_stack(tsk))
> > +		return -EINVAL;
> > +
> > +	ret = __save_stack_trace_reliable(trace, tsk);
> 
> __save_stack_trace_reliable() returns -1 in case of problems.
> But this function returns a meaningful error codes, line -EINVAL,
> -ENOSYS, otherwise.
> 
> We should either transform the error code here to something
> "meaningful", probably -EINVAL. Or we should update
> __save_stack_trace_reliable() to return meaningful error codes.

Agreed.

> > +	put_task_stack(tsk);
> > +
> > +	return ret;
> > +}
> > +#endif /* CONFIG_HAVE_RELIABLE_STACKTRACE */
> > +
> >  /* Userspace stacktrace - based on kernel/trace/trace_sysprof.c */
> >  
> >  struct stack_frame_user {
> 
> Otherwise, all the logic looks fine to me. Great work!

Thanks!

-- 
Josh

  reply	other threads:[~2017-01-26 17:57 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-19 15:46 [PATCH v4 00/15] livepatch: hybrid consistency model Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 01/15] stacktrace/x86: add function for detecting reliable stack traces Josh Poimboeuf
2017-01-26 13:56   ` Petr Mladek
2017-01-26 17:57     ` Josh Poimboeuf [this message]
2017-01-27  8:47   ` Miroslav Benes
2017-01-27 17:13     ` Josh Poimboeuf
2017-02-01 19:57   ` [PATCH v4.1 " Josh Poimboeuf
2017-02-02 14:39     ` Miroslav Benes
2017-01-19 15:46 ` [PATCH v4 02/15] x86/entry: define _TIF_ALLWORK_MASK flags explicitly Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 03/15] livepatch: create temporary klp_update_patch_state() stub Josh Poimboeuf
2017-01-27  8:52   ` Miroslav Benes
2017-01-19 15:46 ` [PATCH v4 04/15] livepatch/x86: add TIF_PATCH_PENDING thread flag Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 05/15] livepatch/powerpc: " Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 06/15] livepatch/s390: reorganize TIF thread flag bits Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 07/15] livepatch/s390: add TIF_PATCH_PENDING thread flag Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 08/15] livepatch: separate enabled and patched states Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 09/15] livepatch: remove unnecessary object loaded check Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 10/15] livepatch: move patching functions into patch.c Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 11/15] livepatch: use kstrtobool() in enabled_store() Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 12/15] livepatch: store function sizes Josh Poimboeuf
2017-01-19 15:46 ` [PATCH v4 13/15] livepatch: change to a per-task consistency model Josh Poimboeuf
2017-02-02 11:45   ` Petr Mladek
2017-02-02 11:47     ` Petr Mladek
2017-02-02 11:51   ` Petr Mladek
2017-02-03 16:21     ` Miroslav Benes
2017-02-03 20:39     ` Josh Poimboeuf
2017-02-06 16:44       ` Petr Mladek
2017-02-06 19:51         ` Josh Poimboeuf
2017-02-08 15:47           ` Petr Mladek
2017-02-08 16:46             ` Josh Poimboeuf
2017-02-09 10:24               ` Petr Mladek
2017-02-03 16:41   ` Miroslav Benes
2017-02-06 15:58     ` Josh Poimboeuf
2017-02-07  8:21       ` Miroslav Benes
2017-01-19 15:46 ` [PATCH v4 14/15] livepatch: add /proc/<pid>/patch_state Josh Poimboeuf
2017-01-31 14:31   ` Miroslav Benes
2017-01-31 14:56     ` Josh Poimboeuf
2017-02-01  8:54       ` Miroslav Benes
2017-01-19 15:46 ` [PATCH v4 15/15] livepatch: allow removal of a disabled patch Josh Poimboeuf
2017-02-03 16:48   ` Miroslav Benes
2017-02-01 20:02 ` [PATCH v4 00/15] livepatch: hybrid consistency model Josh Poimboeuf
2017-02-01 20:52   ` Miroslav Benes
2017-02-01 21:01   ` Jiri Kosina
2017-02-02 14:37   ` Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170126175744.gv3ttlg52axuq57c@treble \
    --to=jpoimboe@redhat.com \
    --cc=bsingharora@gmail.com \
    --cc=chris.j.arges@canonical.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=jeyu@redhat.com \
    --cc=jikos@kernel.org \
    --cc=jslaby@suse.cz \
    --cc=kamalesh@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=live-patching@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mbenes@suse.cz \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=peterz@infradead.org \
    --cc=pmladek@suse.com \
    --cc=vojtech@suse.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.