[elf][regset] simplify thread list handling in fill_note_info()
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 8 Jun 2020 17:44:16 +0000 (13:44 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 23 Oct 2022 22:06:56 +0000 (18:06 -0400)
fill_note_info() iterates through the list of threads collected in
mm->core_state->dumper, allocating a struct elf_thread_core_info
instance for each and linking those into a list.

We need the entry corresponding to current to be first in the
resulting list, so the logics for list insertion is
if it's for current or list is empty
insert in the head
else
insert after the first element

However, in mm->core_state->dumper the entry for current is guaranteed
to be the first one.  Which means that both parts of condition will
be true on the first iteration and neither will be true on all subsequent
ones.

Taking the first iteration out of the loop simplifies things nicely...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/binfmt_elf.c

index 4190dafd2ec445f9130302d75e6a241d159a0150..e990075fb43dab7da98a5c8f903c50bbca6dfd89 100644 (file)
@@ -1866,7 +1866,14 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
        /*
         * Allocate a structure for each thread.
         */
-       for (ct = &dump_task->signal->core_state->dumper; ct; ct = ct->next) {
+       info->thread = kzalloc(offsetof(struct elf_thread_core_info,
+                                    notes[info->thread_notes]),
+                           GFP_KERNEL);
+       if (unlikely(!info->thread))
+               return 0;
+
+       info->thread->task = dump_task;
+       for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) {
                t = kzalloc(offsetof(struct elf_thread_core_info,
                                     notes[info->thread_notes]),
                            GFP_KERNEL);
@@ -1874,17 +1881,8 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
                        return 0;
 
                t->task = ct->task;
-               if (ct->task == dump_task || !info->thread) {
-                       t->next = info->thread;
-                       info->thread = t;
-               } else {
-                       /*
-                        * Make sure to keep the original task at
-                        * the head of the list.
-                        */
-                       t->next = info->thread->next;
-                       info->thread->next = t;
-               }
+               t->next = info->thread->next;
+               info->thread->next = t;
        }
 
        /*