Commit 4dd537ac authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)
Browse files

tracing: uprobes: Re-enable $comm support for uprobe events

Since commit 53305928 ("tracing: probeevent: Introduce new
argument fetching code") dropped the $comm support from uprobe
events, this re-enables it.

For $comm support, uses strlcpy() instead of strncpy_from_user()
to copy current task's comm. Because it is in the kernel space,
strncpy_from_user() always fails to copy the comm.
This also uses strlen() instead of strnlen_user() to measure the
length of the comm.

Note that this uses -ECOMM as a token value to fetch the comm
string. If the user-space pointer points -ECOMM, it will be
translated to task->comm.

Link: http://lkml.kernel.org/r/155723734162.9149.4042756162201097965.stgit@devnote2



Fixes: 53305928 ("tracing: probeevent: Introduce new argument fetching code")
Reported-by: default avatarAndreas Ziegler <andreas.ziegler@fau.de>
Acked-by: default avatarAndreas Ziegler <andreas.ziegler@fau.de>
Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 9e298e86
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ struct fetch_insn {

/* fetch + deref*N + store + mod + end <= 16, this allows N=12, enough */
#define FETCH_INSN_MAX	16
#define FETCH_TOKEN_COMM	(-ECOMM)

/* Fetch type information table */
struct fetch_type {
+11 −2
Original line number Diff line number Diff line
@@ -156,6 +156,9 @@ fetch_store_string(unsigned long addr, void *dest, void *base)
	if (unlikely(!maxlen))
		return -ENOMEM;

	if (addr == FETCH_TOKEN_COMM)
		ret = strlcpy(dst, current->comm, maxlen);
	else
		ret = strncpy_from_user(dst, src, maxlen);
	if (ret >= 0) {
		if (ret == maxlen)
@@ -180,6 +183,9 @@ fetch_store_strlen(unsigned long addr)
	int len;
	void __user *vaddr = (void __force __user *) addr;

	if (addr == FETCH_TOKEN_COMM)
		len = strlen(current->comm) + 1;
	else
		len = strnlen_user(vaddr, MAX_STRING_SIZE);

	return (len > MAX_STRING_SIZE) ? 0 : len;
@@ -220,6 +226,9 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
	case FETCH_OP_IMM:
		val = code->immediate;
		break;
	case FETCH_OP_COMM:
		val = FETCH_TOKEN_COMM;
		break;
	case FETCH_OP_FOFFS:
		val = translate_user_vaddr(code->immediate);
		break;