diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c index 88a16c572282..ea5f748906a8 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1623,6 +1623,41 @@ expand_fail: return ret; } +static int cn_print_exe_file(struct core_name *cn) +{ + struct file *exe_file; + char *pathbuf, *path, *p; + int ret; + + exe_file = get_mm_exe_file(current->mm); + if (!exe_file) + return cn_printf(cn, "(unknown)"); + + pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); + if (!pathbuf) { + ret = -ENOMEM; + goto put_exe_file; + } + + path = d_path(&exe_file->f_path, pathbuf, PATH_MAX); + if (IS_ERR(path)) { + ret = PTR_ERR(path); + goto free_buf; + } + + for (p = path; *p; p++) + if (*p == '/') + *p = '!'; + + ret = cn_printf(cn, "%s", path); + +free_buf: + kfree(pathbuf); +put_exe_file: + fput(exe_file); + return ret; +} + /* format_corename will inspect the pattern parameter, and output a * name into corename, which must have space for at least * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. @@ -1694,6 +1729,9 @@ static int format_corename(struct core_name *cn, long signr) case 'e': err = cn_printf(cn, "%s", current->comm); break; + case 'E': + err = cn_print_exe_file(cn); + break; /* core limit size */ case 'c': err = cn_printf(cn, "%lu", |