Unverified Commit 3bbb0f88 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11544 Fix CVE-2024-45025

Merge Pull Request from: @ci-robot 
 
PR sync from: Long Li <leo.lilong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/JYQNDUY77VPNQ2R3OH6TDFFUJSUUC426/ 
This patch set fix cve-2024-45025

Al Viro (1):
  fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE

Alexander Lobakin (2):
  bitmap: introduce generic optimized bitmap_size()
  s390/cio: rename bitmap_size() -> idset_bitmap_size()


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/IAQOJ9 
 
Link:https://gitee.com/openeuler/kernel/pulls/11544

 

Reviewed-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents 369b68f4 e1631939
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -16,20 +16,21 @@ struct idset {
	unsigned long bitmap[0];
};

static inline unsigned long bitmap_size(int num_ssid, int num_id)
static inline unsigned long idset_bitmap_size(int num_ssid, int num_id)
{
	return BITS_TO_LONGS(num_ssid * num_id) * sizeof(unsigned long);
	return bitmap_size(size_mul(num_ssid, num_id));
}

static struct idset *idset_new(int num_ssid, int num_id)
{
	struct idset *set;

	set = vmalloc(sizeof(struct idset) + bitmap_size(num_ssid, num_id));
	set = vmalloc(sizeof(struct idset) +
		      idset_bitmap_size(num_ssid, num_id));
	if (set) {
		set->num_ssid = num_ssid;
		set->num_id = num_id;
		memset(set->bitmap, 0, bitmap_size(num_ssid, num_id));
		memset(set->bitmap, 0, idset_bitmap_size(num_ssid, num_id));
	}
	return set;
}
@@ -41,7 +42,8 @@ void idset_free(struct idset *set)

void idset_fill(struct idset *set)
{
	memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id));
	memset(set->bitmap, 0xff,
	       idset_bitmap_size(set->num_ssid, set->num_id));
}

static inline void idset_add(struct idset *set, int ssid, int id)
+13 −17
Original line number Diff line number Diff line
@@ -44,27 +44,23 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
#define BITBIT_NR(nr)	BITS_TO_LONGS(BITS_TO_LONGS(nr))
#define BITBIT_SIZE(nr)	(BITBIT_NR(nr) * sizeof(long))

#define fdt_words(fdt) ((fdt)->max_fds / BITS_PER_LONG) // words in ->open_fds
/*
 * Copy 'count' fd bits from the old table to the new table and clear the extra
 * space if any.  This does not copy the file pointers.  Called with the files
 * spinlock held for write.
 */
static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
			    unsigned int count)
static inline void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
			    unsigned int copy_words)
{
	unsigned int cpy, set;
	unsigned int nwords = fdt_words(nfdt);

	cpy = count / BITS_PER_BYTE;
	set = (nfdt->max_fds - count) / BITS_PER_BYTE;
	memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
	memset((char *)nfdt->open_fds + cpy, 0, set);
	memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
	memset((char *)nfdt->close_on_exec + cpy, 0, set);

	cpy = BITBIT_SIZE(count);
	set = BITBIT_SIZE(nfdt->max_fds) - cpy;
	memcpy(nfdt->full_fds_bits, ofdt->full_fds_bits, cpy);
	memset((char *)nfdt->full_fds_bits + cpy, 0, set);
	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);
}

/*
@@ -82,7 +78,7 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
	memcpy(nfdt->fd, ofdt->fd, cpy);
	memset((char *)nfdt->fd + cpy, 0, set);

	copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
	copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt));
}

static struct fdtable * alloc_fdtable(unsigned int nr)
@@ -337,7 +333,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
		open_files = count_open_files(old_fdt);
	}

	copy_fd_bitmaps(new_fdt, old_fdt, open_files);
	copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG);

	old_fds = old_fdt->fd;
	new_fds = new_fdt->fd;
+17 −3
Original line number Diff line number Diff line
@@ -212,12 +212,14 @@ extern int bitmap_print_to_pagebuf(bool list, char *buf,
#define small_const_nbits(nbits) \
	(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG && (nbits) > 0)

#define bitmap_size(nbits)	(ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)

static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
{
	if (small_const_nbits(nbits))
		*dst = 0UL;
	else {
		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
		unsigned int len = bitmap_size(nbits);
		memset(dst, 0, len);
	}
}
@@ -227,7 +229,7 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
	if (small_const_nbits(nbits))
		*dst = ~0UL;
	else {
		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
		unsigned int len = bitmap_size(nbits);
		memset(dst, 0xff, len);
	}
}
@@ -238,7 +240,7 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
	if (small_const_nbits(nbits))
		*dst = *src;
	else {
		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
		unsigned int len = bitmap_size(nbits);
		memcpy(dst, src, len);
	}
}
@@ -254,6 +256,18 @@ static inline void bitmap_copy_clear_tail(unsigned long *dst,
		dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
}

static inline void bitmap_copy_and_extend(unsigned long *to,
					  const unsigned long *from,
					  unsigned int count, unsigned int size)
{
	unsigned int copy = BITS_TO_LONGS(count);

	memcpy(to, from, copy * sizeof(long));
	if (count % BITS_PER_LONG)
		to[copy - 1] &= BITMAP_LAST_WORD_MASK(count);
	memset(to + copy, 0, bitmap_size(size) - copy * sizeof(long));
}

/*
 * On 32-bit systems bitmaps are represented as u32 arrays internally, and
 * therefore conversion is not needed when copying data from/to arrays of u32.
+1 −1
Original line number Diff line number Diff line
@@ -656,7 +656,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
 */
static inline unsigned int cpumask_size(void)
{
	return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long);
	return bitmap_size(nr_cpumask_bits);
}

/*
+4 −3
Original line number Diff line number Diff line
@@ -27,13 +27,14 @@ int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
#define small_const_nbits(nbits) \
	(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)

#define bitmap_size(nbits)	(ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)

static inline void bitmap_zero(unsigned long *dst, int nbits)
{
	if (small_const_nbits(nbits))
		*dst = 0UL;
	else {
		int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
		memset(dst, 0, len);
		memset(dst, 0, bitmap_size(nbits));
	}
}

@@ -119,7 +120,7 @@ static inline int test_and_clear_bit(int nr, unsigned long *addr)
 */
static inline unsigned long *bitmap_alloc(int nbits)
{
	return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
	return calloc(1, bitmap_size(nbits));
}

/*