Skip to contentSkip to conversation

coredump: use task comm instead of (unknown)

PATCH Superseded Jiri Slaby 3 participants 8 messages May 4, 2011 – May 7, 2011 1 message not in the archive

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Jiri Slaby

author
#1 lore raw

PATCH 1/1 coredump: use task comm instead of (unknown)

If we don't know the file corresponding to the binary (i.e. exe_file is unknown), use "task->comm (path unknown)" instead of simple "(unknown)" as suggested by ak.

The fallback is the same as %e except it will append "(path unknown)".

Cc Alan Cox <[email protected]>
Cc Al Viro <[email protected]>
Cc Andi Kleen <[email protected]>
---
 fs/exec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
fs/exec.c +1 -1
index 5ee7562..0a4d281 100644
@@ -1555,7 +1555,7 @@ static int cn_print_exe_file(struct core_name *cn)
 
 	exe_file = get_mm_exe_file(current->mm);
 	if (!exe_file)
-		return cn_printf(cn, "(unknown)");
+		return cn_printf(cn, "%s (path unknown)", current->comm);
 
 	pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
 	if (!pathbuf) {
Signature · 9 lines
1.7.4.2


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
maintainer
#2 lore raw
Quoted 19 lines · On Wed, 4 May 2011 09:32:34 +0200 Jiri Slaby <[email protected]> wrote:

If we don't know the file corresponding to the binary (i.e. exe_file is unknown), use "task->comm (path unknown)" instead of simple "(unknown)" as suggested by ak.

The fallback is the same as %e except it will append "(path unknown)".

Cc Alan Cox <[email protected]>
Cc Al Viro <[email protected]>
Cc Andi Kleen <[email protected]>
---
 fs/exec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
fs/exec.c +0 -0
index 5ee7562..0a4d281 100644

fs/exec.c static int cn_print_exe_file(struct core_name *cn) · line 1561

Quoted 8 lines
fs/exec.c +1 -1
@@ -1555,7 +1555,7 @@ static int cn_print_exe_file(struct core_name *cn)
 
 	exe_file = get_mm_exe_file(current->mm);
 	if (!exe_file)
-		return cn_printf(cn, "(unknown)");
+		return cn_printf(cn, "%s (path unknown)", current->comm);
 
 	pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
 	if (!pathbuf) {

Direct access to current->comm is racy since we added prctl(PR_SET_NAME).

Hopefully John Stultz will soon be presenting us with a %p modifier for displaying task_struct.comm.

But we should get this settled pretty promptly as this is a form of userspace-visible API. Use get_task_comm() for now.

Also, there's nothing which prevents userspace from rewriting task->comm to something which contains slashes (this seems bad). If that is done, your patch will do Bad Things - it should be modified to use cn_print_exe_file()'s slash-overwriting codepath.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

author
#3 lore raw

Ccing Oleg.

Quoted 28 lines · Andrew Morton
Quoted 25 lines · On Wed, 4 May 2011 09:32:34 +0200 Jiri Slaby <[email protected]> wrote:

If we don't know the file corresponding to the binary (i.e. exe_file is unknown), use "task->comm (path unknown)" instead of simple "(unknown)" as suggested by ak.

The fallback is the same as %e except it will append "(path unknown)".

Cc Alan Cox <[email protected]>
Cc Al Viro <[email protected]>
Cc Andi Kleen <[email protected]>
---
 fs/exec.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
fs/exec.c +1 -1
index 5ee7562..0a4d281 100644
@@ -1555,7 +1555,7 @@ static int cn_print_exe_file(struct core_name *cn)
 
 	exe_file = get_mm_exe_file(current->mm);
 	if (!exe_file)
-		return cn_printf(cn, "(unknown)");
+		return cn_printf(cn, "%s (path unknown)", current->comm);
 
Quoted 8 lines

fs/exec.c static int cn_print_exe_file(struct core_name *cn) · line 1561

Quoted 2 lines
fs/exec.c +0 -0
 	pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
 	if (!pathbuf) {

Direct access to current->comm is racy since we added prctl(PR_SET_NAME).

Hopefully John Stultz will soon be presenting us with a %p modifier for displaying task_struct.comm.

Then just make sure, you won't nest alloc_lock (task_lock) into siglock.

Quoted 2 lines

But we should get this settled pretty promptly as this is a form of userspace-visible API. Use get_task_comm() for now.

I thought about using get_task_comm, but was not sure, if it is safe to task_lock() at that place. Note that this is copied from %e.

Quoted 4 lines

Also, there's nothing which prevents userspace from rewriting task->comm to something which contains slashes (this seems bad). If that is done, your patch will do Bad Things - it should be modified to use cn_print_exe_file()'s slash-overwriting codepath.

%E (cn_print_exe_file) does exactly what %e (format_corename) does. So if this is really broken in the two ways, we should fix both the old %e and the new %E.

I'm not sure whether at this point when the task is being killed and dumped, it can still change comm?

For the slashes, I agree. That should be fixed in both cases.

thanks,

Signature · 9 lines
js
suse labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#4 lore raw
In reply to Andrew Morton
Quoted 2 lines · Andrew Morton

Direct access to current->comm is racy since we added prctl(PR_SET_NAME).

A passer-by's question. Did we change below one

char *get_task_comm(char *buf, struct task_struct *tsk)

{
	/* buf must be at least sizeof(tsk->comm) in size */
	task_lock(tsk);
	strncpy(buf, tsk->comm, sizeof(tsk->comm));
	task_unlock(tsk);
	return buf;
}

since some archs may do like

char *strncpy(char *dest, const char *src, size_t n)

{
	size_t len = __strnend(src, n) - src;
	__builtin_memset(dest + len, 0, n - len);
	__builtin_memcpy(dest, src, len);
	return dest;
}

( arch/s390/lib/string.c ) after adding prctl(PR_SET_NAME)?

maintainer
#5 lore raw

(Cc John)

Quoted 18 lines · On Fri, 6 May 2011 21:26:39 +0900 Tetsuo Handa…
Quoted 2 lines · Andrew Morton

Direct access to current->comm is racy since we added prctl(PR_SET_NAME).

A passer-by's question. Did we change below one

char *get_task_comm(char *buf, struct task_struct *tsk)

{
	/* buf must be at least sizeof(tsk->comm) in size */
	task_lock(tsk);
	strncpy(buf, tsk->comm, sizeof(tsk->comm));
	task_unlock(tsk);
	return buf;
}

since some archs may do like

char *strncpy(char *dest, const char *src, size_t n)

Quoted 8 lines
{
	size_t len = __strnend(src, n) - src;
	__builtin_memset(dest + len, 0, n - len);
	__builtin_memcpy(dest, src, len);
	return dest;
}

( arch/s390/lib/string.c ) after adding prctl(PR_SET_NAME)?

I don't understand what you're asking, sorry.

#6 lore raw
Quoted 3 lines · Andrew Morton
Quoted 3 lines

char *strncpy(char *dest, const char *src, size_t n)

{
	size_t len = __strnend(src, n) - src;

If src was overwritten by prctl(PR_SET_NAME) at this moment (i.e. after len was calculated),

Quoted 2 lines
Quoted 2 lines
	__builtin_memset(dest + len, 0, n - len);
	__builtin_memcpy(dest, src, len);

won't this result in inconsistent copying of src when length of src has changed by prctl(PR_SET_NAME)?

Quoted 2 lines
Quoted 2 lines
	return dest;
}

This strncpy() assumes that length of src won't change within the function. I thought prctl(PR_SET_NAME) might break such assumption.

maintainer
#7 lore raw
Quoted 11 lines · On Sat, 7 May 2011 11:14:14 +0900 Tetsuo Handa…
Quoted 3 lines · Andrew Morton
Quoted 3 lines

char *strncpy(char *dest, const char *src, size_t n)

{
	size_t len = __strnend(src, n) - src;

If src was overwritten by prctl(PR_SET_NAME) at this moment (i.e. after len was calculated),

Quoted 2 lines
Quoted 2 lines
	__builtin_memset(dest + len, 0, n - len);
	__builtin_memcpy(dest, src, len);
Quoted 8 lines

won't this result in inconsistent copying of src when length of src has changed by prctl(PR_SET_NAME)?

Quoted 2 lines
Quoted 2 lines
	return dest;
}

This strncpy() assumes that length of src won't change within the function. I thought prctl(PR_SET_NAME) might break such assumption.

PR_SET_NAME uses set_task_comm() which has appropriate locking to protect against get_task_comm().

If kernel code directly accesses task->comm without taking task_lock() then yes, it's racy.

#8 lore raw
Quoted 5 lines · Andrew Morton

PR_SET_NAME uses set_task_comm() which has appropriate locking to protect against get_task_comm().

If kernel code directly accesses task->comm without taking task_lock() then yes, it's racy.

I see. Well,

grep -r -- '->comm[,;)]' .

in 2.6.39-rc6 shows so many users directly reading/updating, including

	case 'e':
		err = cn_printf(cn, "%s", current->comm);
		break;

in format_corename().

Quoted 2 lines

Hopefully John Stultz will soon be presenting us with a %p modifier for displaying task_struct.comm.

That will be nice. But caller might by error call printk() with that modifier between task_lock() and task_unlock().