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;

Reply via email to