The offset in the core file used to be tracked with ->written field of
the coredump_params structure. The field was retired in favour of
file->f_pos.
However, ->f_pos is not maintained for pipes which leads to breakage.
Restore explicit tracking of the offset in coredump_params. Introduce
->pos field for this purpose since ->written was already reused.
Fixes: a00839395103 ("get rid of coredump_params->written").
Reported-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
        if (rc < 0)
                goto out;
 
-       skip = roundup(cprm->file->f_pos - total + sz, 4) - cprm->file->f_pos;
+       skip = roundup(cprm->pos - total + sz, 4) - cprm->pos;
        if (!dump_skip(cprm, skip))
                goto Eio;
 out:
 
                goto end_coredump;
 
        /* Align to page */
-       if (!dump_skip(cprm, dataoff - cprm->file->f_pos))
+       if (!dump_skip(cprm, dataoff - cprm->pos))
                goto end_coredump;
 
        for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
 
                                goto end_coredump;
        }
 
-       if (!dump_skip(cprm, dataoff - cprm->file->f_pos))
+       if (!dump_skip(cprm, dataoff - cprm->pos))
                goto end_coredump;
 
        if (!elf_fdpic_dump_segments(cprm))
 
                        return 0;
                file->f_pos = pos;
                cprm->written += n;
+               cprm->pos += n;
                nr -= n;
        }
        return 1;
                if (dump_interrupted() ||
                    file->f_op->llseek(file, nr, SEEK_CUR) < 0)
                        return 0;
+               cprm->pos += nr;
                return 1;
        } else {
                while (nr > PAGE_SIZE) {
 
 int dump_align(struct coredump_params *cprm, int align)
 {
-       unsigned mod = cprm->file->f_pos & (align - 1);
+       unsigned mod = cprm->pos & (align - 1);
        if (align & (align - 1))
                return 0;
        return mod ? dump_skip(cprm, align - mod) : 1;
 
        unsigned long limit;
        unsigned long mm_flags;
        loff_t written;
+       loff_t pos;
 };
 
 /*