Re: [PATCH] fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE

Al Viro
2024-08-04T03:47:41Z

On Sun, Aug 04, 2024 at 01:34:05AM +0100, Al Viro wrote:

> static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
> unsigned int count, unsigned int size)
> {
> bitmap_copy_and_extend(nfdt->open_fds, ofdt->open_fds,
> count, size);
> bitmap_copy_and_extend(nfdt->close_on_exec, ofdt->close_on_exec,
> count, size);
> bitmap_copy_and_extend(nfdt->full_fds_bits, ofdt->full_fds_bits,
> count / BITS_PER_LONG, size / BITS_PER_LONG);
> }

One variant would be

#define fdt_words(fdt) ((fdt)->max_fds / BITS_PER_LONG) /* longs in fdt->open_fds[] */

static inline void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
unsigned int copy_words)
{
unsigned int nwords = fdt_words(nfdt);

bitmap_copy_and_extend(nfdt->open_fds, ofdt->open_fds,
copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);
bitmap_copy_and_extend(nfdt->close_on_exec, ofdt->close_on_exec,
copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);
bitmap_copy_and_extend(nfdt->full_fds_bits, ofdt->full_fds_bits,
copy_words, nwords);
}
with callers being
copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt));
and
copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG);

resp. That would compile into pure memcpy()+memset() for the main bitmaps
and at least as good as bitmap_copy()+bitmap_clear() for full_fds_bits...