BACKPORT: coredump: add %f for executable filename

The document reads "%e" should be "executable filename" while actually it
could be changed by things like pr_ctl PR_SET_NAME.  People who uses "%e"
in core_pattern get surprised when they find out they get thread name
instead of executable filename.

This is either a bug of document or a bug of code.  Since the behavior of
"%e" is there for long time, it could bring another surprise for users if
we "fix" the code.

So we just "fix" the document.  And more, for users who really need the
"executable filename" in core_pattern, we introduce a new "%f" for the
real executable filename.  We already have "%E" for executable path in
kernel, so just reuse most of its code for the new added "%f" format.

Signed-off-by: Lepton Wu <ytht.net@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/20200701031432.2978761-1-ytht.net@gmail.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
(cherry picked from commit f38c85f1ba6902e4e2e2bf1b84edf065a904cdeb)

  - backport:
     Fix conflicts in fs/coredump.c and update Documentation/sysctl/kernel.txt
BUG=chromium:1115730
TEST=CQ

Change-Id: I4c8067de34bb7cff39905eb1008701cafc6ea3b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2353891
Commit-Queue: Lepton Wu <lepton@chromium.org>
Commit-Queue: Guenter Roeck <groeck@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Auto-Submit: Lepton Wu <lepton@chromium.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 833026d..6c89342 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -190,7 +190,8 @@
 	%s	signal number
 	%t	UNIX time of dump
 	%h	hostname
-	%e	executable filename (may be shortened)
+	%e      executable filename (may be shortened, could be changed by prctl etc)
+	%f      executable filename
 	%E	executable path
 	%<OTHER> both are dropped
 . If the first character of the pattern is a '|', the kernel will treat
diff --git a/fs/coredump.c b/fs/coredump.c
index 997b967..54d7ac8 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -108,10 +108,10 @@
 			*str = '!';
 }
 
-static int cn_print_exe_file(struct core_name *cn)
+static int cn_print_exe_file(struct core_name *cn, bool name_only)
 {
 	struct file *exe_file;
-	char *pathbuf, *path;
+	char *pathbuf, *path, *ptr;
 	int ret;
 
 	exe_file = get_mm_exe_file(current->mm);
@@ -134,6 +134,12 @@
 		goto free_buf;
 	}
 
+	if (name_only) {
+		ptr = strrchr(path, '/');
+		if (ptr)
+			path = ptr + 1;
+	}
+
 	cn_escape(path);
 
 	ret = cn_printf(cn, "%s", path);
@@ -224,15 +230,19 @@
 				cn_escape(namestart);
 				break;
 			}
-			/* executable */
+			/* executable, could be changed by prctl PR_SET_NAME etc */
 			case 'e': {
 				char *commstart = cn->corename + cn->used;
 				err = cn_printf(cn, "%s", current->comm);
 				cn_escape(commstart);
 				break;
 			}
+			/* file name of executable */
+			case 'f':
+				err = cn_print_exe_file(cn, true);
+				break;
 			case 'E':
-				err = cn_print_exe_file(cn);
+				err = cn_print_exe_file(cn, false);
 				break;
 			/* core limit size */
 			case 'c':