发布时间: 2024年9月27日
修改时间: 2024年10月12日
In the Linux kernel, the following vulnerability has been resolved:fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHAREcopy_fd_bitmaps(new, old, count) is expected to copy the firstcount/BITS_PER_LONG bits from old->full_fds_bits[] and fillthe rest with zeroes. What it does is copying enough words(BITS_TO_LONGS(count/BITS_PER_LONG)), then memsets the rest.That works fine, *if* all bits past the cutoff point areclear. Otherwise we are risking garbage from the last wordwe d copied.For most of the callers that is true - expand_fdtable() hascount equal to old->max_fds, so there s no open descriptorspast count, let alone fully occupied words in ->open_fds[],which is what bits in ->full_fds_bits[] correspond to.The other caller (dup_fd()) passes sane_fdtable_size(old_fdt, max_fds),which is the smallest multiple of BITS_PER_LONG that covers allopened descriptors below max_fds. In the common case (copying onfork()) max_fds is ~0U, so all opened descriptors will be belowit and we are fine, by the same reasons why the call in expand_fdtable()is safe.Unfortunately, there is a case where max_fds is less than thatand where we might, indeed, end up with junk in ->full_fds_bits[] -close_range(from, to, CLOSE_RANGE_UNSHARE) with * descriptor table being currently shared * to being above the current capacity of descriptor table * from being just under some chunk of opened descriptors.In that case we end up with observably wrong behaviour - e.g. spawna child with CLONE_FILES, get all descriptors in range 0..127 open,then close_range(64, ~0U, CLOSE_RANGE_UNSHARE) and watch dup(0) endingup with descriptor #128, despite #64 being observably not open.The minimally invasive fix would be to deal with that in dup_fd().If this proves to add measurable overhead, we can go that way, butlet s try to fix copy_fd_bitmaps() first.* new helper: bitmap_copy_and_expand(to, from, bits_to_copy, size).* make copy_fd_bitmaps() take the bitmap size in words, rather thanbits; it s count argument is always a multiple of BITS_PER_LONG,so we are not losing any information, and that way we can use thesame helper for all three bitmaps - compiler will see that countis a multiple of BITS_PER_LONG for the large ones, so it ll generateplain memcpy()+memset().Reproducer added to tools/testing/selftests/core/close_range_test.c
NVD | openEuler | |
---|---|---|
CVSS评分 | 5.5 | 5.5 |
Attack Vector | Local | Local |
Attack Complexity | Low | Low |
Privileges Required | Low | Low |
User Interaction | None | None |
Scope | Unchanged | Unchanged |
Confidentiality | None | None |
Integrity | None | None |
Availability | High | High |
公告名 | 概要 | 发布时间 |
---|---|---|
KylinSec-SA-2024-4871 | kernel security update | 2024年9月27日 |
产品 | 包 | 状态 |
---|---|---|
KY3.4-5A | kernel | Fixed |
KY3.5.2 | kernel | Fixed |
V6 | kernel | Fixed |