[GIT pull] core fixes for 4.14

From: Thomas Gleixner
Date: Sun Sep 17 2017 - 05:36:25 EST


Linus,

please pull the latest core-urgent-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

This update contains:

- A fix for a user space regression in /proc/$PID/stat

- A couple of objtool fixes:

- Plug a memory leak

- Avoid accessing empty sections which upsets certain binutil versions

- Prevent corrupting the obj file when section sizes did not change

Thanks,

tglx

------------------>
John Ogness (1):
fs/proc: Report eip/esp in /prod/PID/stat for coredumping

Josh Poimboeuf (1):
objtool: Fix object file corruption

Martin Kepplinger (1):
objtool: Fix memory leak in elf_create_rela_section()

Petr Vandrovec (1):
objtool: Do not retrieve data from empty sections


fs/proc/array.c | 9 +++++++++
tools/objtool/elf.c | 33 ++++++++++++++++++++-------------
2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/fs/proc/array.c b/fs/proc/array.c
index 88c355574aa0..525157ca25cb 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -62,6 +62,7 @@
#include <linux/mman.h>
#include <linux/sched/mm.h>
#include <linux/sched/numa_balancing.h>
+#include <linux/sched/task_stack.h>
#include <linux/sched/task.h>
#include <linux/sched/cputime.h>
#include <linux/proc_fs.h>
@@ -421,7 +422,15 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
* esp and eip are intentionally zeroed out. There is no
* non-racy way to read them without freezing the task.
* Programs that need reliable values can use ptrace(2).
+ *
+ * The only exception is if the task is core dumping because
+ * a program is not able to use ptrace(2) in that case. It is
+ * safe because the task has stopped executing permanently.
*/
+ if (permitted && (task->flags & PF_DUMPCORE)) {
+ eip = KSTK_EIP(task);
+ esp = KSTK_ESP(task);
+ }
}

get_task_comm(tcomm, task);
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 6e9f980a7d26..24460155c82c 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -175,19 +175,20 @@ static int read_sections(struct elf *elf)
return -1;
}

- sec->data = elf_getdata(s, NULL);
- if (!sec->data) {
- WARN_ELF("elf_getdata");
- return -1;
- }
-
- if (sec->data->d_off != 0 ||
- sec->data->d_size != sec->sh.sh_size) {
- WARN("unexpected data attributes for %s", sec->name);
- return -1;
+ if (sec->sh.sh_size != 0) {
+ sec->data = elf_getdata(s, NULL);
+ if (!sec->data) {
+ WARN_ELF("elf_getdata");
+ return -1;
+ }
+ if (sec->data->d_off != 0 ||
+ sec->data->d_size != sec->sh.sh_size) {
+ WARN("unexpected data attributes for %s",
+ sec->name);
+ return -1;
+ }
}
-
- sec->len = sec->data->d_size;
+ sec->len = sec->sh.sh_size;
}

/* sanity check, one more call to elf_nextscn() should return NULL */
@@ -508,6 +509,7 @@ struct section *elf_create_rela_section(struct elf *elf, struct section *base)
strcat(relaname, base->name);

sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0);
+ free(relaname);
if (!sec)
return NULL;

@@ -561,6 +563,7 @@ int elf_write(struct elf *elf)
struct section *sec;
Elf_Scn *s;

+ /* Update section headers for changed sections: */
list_for_each_entry(sec, &elf->sections, list) {
if (sec->changed) {
s = elf_getscn(elf->elf, sec->idx);
@@ -568,13 +571,17 @@ int elf_write(struct elf *elf)
WARN_ELF("elf_getscn");
return -1;
}
- if (!gelf_update_shdr (s, &sec->sh)) {
+ if (!gelf_update_shdr(s, &sec->sh)) {
WARN_ELF("gelf_update_shdr");
return -1;
}
}
}

+ /* Make sure the new section header entries get updated properly. */
+ elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
+
+ /* Write all changes to the file. */
if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
WARN_ELF("elf_update");
return -1;