__u32 __user *prog_ids, u32 cnt)
 {
        struct bpf_prog **prog;
-       u32 i = 0, id;
-
+       unsigned long err = 0;
+       u32 i = 0, *ids;
+       bool nospc;
+
+       /* users of this function are doing:
+        * cnt = bpf_prog_array_length();
+        * if (cnt > 0)
+        *     bpf_prog_array_copy_to_user(..., cnt);
+        * so below kcalloc doesn't need extra cnt > 0 check, but
+        * bpf_prog_array_length() releases rcu lock and
+        * prog array could have been swapped with empty or larger array,
+        * so always copy 'cnt' prog_ids to the user.
+        * In a rare race the user will see zero prog_ids
+        */
+       ids = kcalloc(cnt, sizeof(u32), GFP_USER);
+       if (!ids)
+               return -ENOMEM;
        rcu_read_lock();
        prog = rcu_dereference(progs)->progs;
        for (; *prog; prog++) {
                if (*prog == &dummy_bpf_prog.prog)
                        continue;
-               id = (*prog)->aux->id;
-               if (copy_to_user(prog_ids + i, &id, sizeof(id))) {
-                       rcu_read_unlock();
-                       return -EFAULT;
-               }
+               ids[i] = (*prog)->aux->id;
                if (++i == cnt) {
                        prog++;
                        break;
                }
        }
+       nospc = !!(*prog);
        rcu_read_unlock();
-       if (*prog)
+       err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
+       kfree(ids);
+       if (err)
+               return -EFAULT;
+       if (nospc)
                return -ENOSPC;
        return 0;
 }