All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joe Lawrence <joe.lawrence@redhat.com>
To: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: jikos@kernel.org, jpoimboe@redhat.com, pmladek@suse.com,
	tglx@linutronix.de
Subject: Re: [PATCH] stacktrace: fix CONFIG_ARCH_STACKWALK stack_trace_save_tsk_reliable return
Date: Fri, 17 May 2019 14:56:36 -0400	[thread overview]
Message-ID: <20190517185636.GA24696@redhat.com> (raw)
In-Reply-To: <20190517185117.24642-1-joe.lawrence@redhat.com>

On Fri, May 17, 2019 at 02:51:17PM -0400, Joe Lawrence wrote:
> Miroslav reported that the livepatch self-tests were failing,
> specifically a case in which the consistency model ensures that we do
> not patch a current executing function, "TEST: busy target module".
> 
> Recent renovations to stack_trace_save_tsk_reliable() left it returning
> only an -ERRNO success indication in some configuration combinations:
> 
>   klp_check_stack()
>     ret = stack_trace_save_tsk_reliable()
>       #ifdef CONFIG_ARCH_STACKWALK && CONFIG_HAVE_RELIABLE_STACKTRACE
>         stack_trace_save_tsk_reliable()
>           ret = arch_stack_walk_reliable()
>             return 0
>             return -EINVAL
>           ...
>           return ret;
>     ...
>     if (ret < 0)
>       /* stack_trace_save_tsk_reliable error */
>     nr_entries = ret;                               << 0
> 
> Previously (and currently for !CONFIG_ARCH_STACKWALK &&
> CONFIG_HAVE_RELIABLE_STACKTRACE) stack_trace_save_tsk_reliable()
> returned the number of entries that it consumed in the passed storage
> array.
> 
> In the case of the above config and trace, be sure to return the
> stacktrace_cookie.len on stack_trace_save_tsk_reliable() success.
> 
> Fixes: 25e39e32b0a3f ("livepatch: Simplify stack trace retrieval")
> Reported-by: Miroslav Benes <mbenes@suse.cz>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
> ---
>  kernel/stacktrace.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c
> index 27bafc1e271e..90d3e0bf0302 100644
> --- a/kernel/stacktrace.c
> +++ b/kernel/stacktrace.c
> @@ -206,7 +206,7 @@ int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
>  
>  	ret = arch_stack_walk_reliable(consume_entry, &c, tsk);
>  	put_task_stack(tsk);
> -	return ret;
> +	return ret ? ret : c.len;
>  }
>  #endif
>  
> -- 
> 2.20.1
> 

Hi Thomas,

This change is *very* lightly tested.  It passes the livepatch
self-tests and a test driver that I wrote to debug this.  If a more
substantial change is needed, feel free to grab this one.

FWIW, here's the debugging module that I used to first verify that the
return code was always 0 (ie, no nr_entries) and then that I was getting
sane values back from the modified version.  It's simple, echo in a task
pointer and it will dump the stack trace to dmesg:

  % dmesg -C
  % echo 0xffff8a4107082f40 > /sys/module/checkstack/parameters/task_param 
  % dmesg
  [ 1909.546463] checkstack: task @ ffff8a4107082f40
  [ 1909.549280] checkstack: nr_entries = 7
  [ 1909.552268] checkstack:      [ffffffffa608fb29] schedule+0x29/0x90
  [ 1909.555583] checkstack:      [ffffffffa60941ed] schedule_hrtimeout_range_clock+0x18d/0x1a0
  [ 1909.556864] checkstack:      [ffffffffa5b27e38] ep_poll+0x428/0x450
  [ 1909.557645] checkstack:      [ffffffffa5b27f10] do_epoll_wait+0xb0/0xd0
  [ 1909.558454] checkstack:      [ffffffffa5b27f4a] __x64_sys_epoll_wait+0x1a/0x20
  [ 1909.559354] checkstack:      [ffffffffa58041e5] do_syscall_64+0x55/0x1a0
  [ 1909.560233] checkstack:      [ffffffffa620008c] entry_SYSCALL_64_after_hwframe+0x44/0xa9

-- Joe

-->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpu.h>
#include <linux/kallsyms.h>
#include <linux/stacktrace.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Joe Lawrence <joe.lawrence@stratus.com>");

#define MAX_STACK_ENTRIES  100

/* No exports, no fun */
static int (*p_stack_trace_save_tsk_reliable)(struct task_struct *tsk, unsigned long *store, unsigned int size);

int checkstack(struct task_struct *task)
{
	static unsigned long entries[MAX_STACK_ENTRIES];
	unsigned long address;
	int ret, nr_entries, i;

	if (!task)
		return 0;

	pr_info("task @ %lx\n", (unsigned long) task);

        ret = p_stack_trace_save_tsk_reliable(task, entries, ARRAY_SIZE(entries));
        WARN_ON_ONCE(ret == -ENOSYS);
        if (ret < 0) {
                pr_err("%s: %s:%d has an unreliable stack\n",
                         __func__, task->comm, task->pid);
                return ret;
        }
	nr_entries = ret;
	pr_info("nr_entries = %d\n", nr_entries); 

        for (i = 0; i < nr_entries; i++) {
                address = entries[i];
		pr_info("\t[%lx] %pS\n", address, (void *) address);
        }

	return 0;
}


static unsigned long task_param = 0;
static int task_param_set(const char *val, const struct kernel_param *kp)
{
        int ret;

        ret = param_set_ulong(val, kp);
        if (ret < 0)
                return ret;

	return checkstack((struct task_struct *)task_param);
}
static const struct kernel_param_ops task_param_ops = {
	.set = task_param_set,
	.get = param_get_ulong,
};
module_param_cb(task_param, &task_param_ops, &task_param, 0644);
MODULE_PARM_DESC(task_param, "task (default=0)");


int __init init_module(void)
{
	p_stack_trace_save_tsk_reliable = 
		(void *)kallsyms_lookup_name("stack_trace_save_tsk_reliable");
	if (!p_stack_trace_save_tsk_reliable) {
		pr_err("can't find stack_trace_save_tsk_reliable symbol\n");
		return -ENXIO;
	}
	pr_info("p_stack_trace_save_tsk_reliable @ %lx\n",
		(unsigned long) p_stack_trace_save_tsk_reliable);

	return 0;
}

void cleanup_module(void)
{
}

  reply	other threads:[~2019-05-17 18:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-17 18:51 [PATCH] stacktrace: fix CONFIG_ARCH_STACKWALK stack_trace_save_tsk_reliable return Joe Lawrence
2019-05-17 18:56 ` Joe Lawrence [this message]
2019-05-17 19:10 ` Josh Poimboeuf
2019-05-18 13:52 ` Kamalesh Babulal
2019-05-19  9:46 ` [tip:core/urgent] stacktrace: Unbreak stack_trace_save_tsk_reliable() tip-bot for Joe Lawrence
2019-05-28 22:25 ` [PATCH] stacktrace: fix CONFIG_ARCH_STACKWALK stack_trace_save_tsk_reliable return Jiri Kosina

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=20190517185636.GA24696@redhat.com \
    --to=joe.lawrence@redhat.com \
    --cc=jikos@kernel.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=pmladek@suse.com \
    --cc=tglx@linutronix.de \
    /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.