From 956f45070d5b0350c9221bd6757864734e324b6a Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Sun, 22 May 2022 23:19:48 +0700 Subject: [PATCH] kernel/vm: Remove default kernel read/write flags `fix_protection` will not apply `B_KERNEL_READ_AREA` and `B_KERNEL_WRITE_AREA` by default. Kernel drivers that directly call `create_area` or `create_area_etc` and do not pass any protection flags have been updated to apply `B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA` instead. Bug: #17751 Change-Id: I43e7ee6b5396e0309cdcff750e28262942c6d01c Reviewed-on: https://review.haiku-os.org/c/haiku/+/5330 Reviewed-by: waddlesplash --- src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp | 2 +- src/add-ons/kernel/bus_managers/scsi/devices.cpp | 3 ++- src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp | 9 +++++---- src/add-ons/kernel/bus_managers/scsi/emulation.cpp | 4 ++-- src/add-ons/kernel/bus_managers/usb/Stack.cpp | 2 +- .../kernel/bus_managers/virtio/VirtioQueue.cpp | 8 ++++---- .../ata/silicon_image_3112/silicon_image_3112.c | 3 ++- .../kernel/busses/scsi/ahci/ahci_controller.cpp | 3 ++- .../drivers/audio/ac97/geode/geode_controller.cpp | 2 +- .../kernel/drivers/audio/hda/hda_controller.cpp | 6 ++++-- .../kernel/generic/ata_adapter/ata_adapter.cpp | 2 +- src/add-ons/kernel/generic/locked_pool/locked_pool.c | 2 +- src/libs/compat/freebsd_network/bus.cpp | 4 ++-- src/system/kernel/vm/vm.cpp | 11 ++++------- 14 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp b/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp index 88c8b99fda..0f0c959fcc 100644 --- a/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp +++ b/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp @@ -589,7 +589,7 @@ Aperture::AllocateMemory(aperture_memory *memory, uint32 flags) void *address; memory->area = create_area("GART memory", &address, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK | ((flags & B_APERTURE_NEED_PHYSICAL) != 0 - ? B_CONTIGUOUS : 0), 0); + ? B_CONTIGUOUS : 0), B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (memory->area < B_OK) { ERROR("Aperture::AllocateMemory(): create_area() failed\n"); return B_NO_MEMORY; diff --git a/src/add-ons/kernel/bus_managers/scsi/devices.cpp b/src/add-ons/kernel/bus_managers/scsi/devices.cpp index 189e7c477a..95e705ac1e 100644 --- a/src/add-ons/kernel/bus_managers/scsi/devices.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/devices.cpp @@ -219,7 +219,8 @@ scsi_create_autosense_request(scsi_device_info *device) // allocate buffer for space sense data and S/G list device->auto_sense_area = create_area("auto_sense", (void**)&buffer, - B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_32_BIT_FULL_LOCK, 0); + B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_32_BIT_FULL_LOCK, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); // TODO: Use B_FULL_LOCK, if addresses >= 4 GB are supported! if (device->auto_sense_area < 0) goto err; diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp index 86d8844bec..8f66bf17a9 100644 --- a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp @@ -193,7 +193,8 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) // TODO: Use 64 bit addresses, if possible! #endif buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size, - B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions, + B_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0, + &virtualRestrictions, &physicalRestrictions, (void**)&buffer->address); if (buffer->area < 0) { @@ -207,7 +208,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) // we can live with a fragmented buffer - very nice buffer->area = create_area("DMA buffer", (void **)&buffer->address, B_ANY_KERNEL_ADDRESS, size, - B_32_BIT_FULL_LOCK, 0); + B_32_BIT_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); // TODO: Use B_FULL_LOCK, if possible! if (buffer->area < 0) { SHOW_ERROR(2, "Cannot create DMA buffer of %" B_PRIu32 " bytes", @@ -226,7 +227,7 @@ scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size) buffer->sg_list_area = create_area("DMA buffer S/G table", (void **)&buffer->sg_list, B_ANY_KERNEL_ADDRESS, sg_list_size, - B_32_BIT_FULL_LOCK, 0); + B_32_BIT_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); // TODO: Use B_FULL_LOCK, if possible! if (buffer->sg_list_area < 0) { SHOW_ERROR( 2, "Cannot create DMA buffer S/G list of %" B_PRIuSIZE @@ -287,7 +288,7 @@ scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, size_t size) buffer->sg_orig = create_area("S/G to original data", (void **)&buffer->sg_list_orig, B_ANY_KERNEL_ADDRESS, size, - B_NO_LOCK, 0); + B_NO_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (buffer->sg_orig < 0) { SHOW_ERROR(2, "Cannot S/G list buffer to original data of %" B_PRIuSIZE " bytes", size); diff --git a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp index 840517a4a0..a7f1fd167b 100644 --- a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp @@ -74,8 +74,8 @@ scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size) physical_address_restrictions physicalRestrictions = {}; physicalRestrictions.alignment = buffer_size; device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer", - total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, - &physicalRestrictions, &address); + total_size, B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, + 0, 0, &virtualRestrictions, &physicalRestrictions, &address); // TODO: Use B_CONTIGUOUS, if possible! if (device->buffer_area < 0) { diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 6badd172e3..b68e73b992 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -331,7 +331,7 @@ Stack::AllocateArea(void **logicalAddress, phys_addr_t *physicalAddress, size_t void *logAddress; size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); area_id area = create_area(name, &logAddress, B_ANY_KERNEL_ADDRESS, size, - B_32_BIT_CONTIGUOUS, 0); + B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); // TODO: Use B_CONTIGUOUS when the TODOs regarding 64 bit physical // addresses are fixed (if possible). diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp index aa5e07f35a..d13fccc066 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp @@ -90,8 +90,8 @@ TransferDescriptor::TransferDescriptor(VirtioQueue* queue, uint16 indirectMaxSiz if (indirectMaxSize > 0) { fAreaSize = indirectMaxSize * sizeof(struct vring_desc); - fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0, - "virtqueue"); + fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "virtqueue"); if (fArea < B_OK) { fStatus = fArea; return; @@ -156,8 +156,8 @@ VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 queueNumber, uint8* virtAddr; phys_addr_t physAddr; fAreaSize = vring_size(fRingSize, device->Alignment()); - fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0, - "virtqueue"); + fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "virtqueue"); if (fArea < B_OK) { fStatus = fArea; return; diff --git a/src/add-ons/kernel/busses/ata/silicon_image_3112/silicon_image_3112.c b/src/add-ons/kernel/busses/ata/silicon_image_3112/silicon_image_3112.c index 5a5993ef2e..7922f69e7e 100644 --- a/src/add-ons/kernel/busses/ata/silicon_image_3112/silicon_image_3112.c +++ b/src/add-ons/kernel/busses/ata/silicon_image_3112/silicon_image_3112.c @@ -454,7 +454,8 @@ channel_init(device_node *node, void **_channelCookie) // used. prdtSize = (ATA_ADAPTER_MAX_SG_COUNT * sizeof(prd_entry) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1); channel->prd_area = create_area("prd", (void **)&channel->prdt, - B_ANY_KERNEL_ADDRESS, prdtSize, B_32_BIT_CONTIGUOUS, 0); + B_ANY_KERNEL_ADDRESS, prdtSize, B_32_BIT_CONTIGUOUS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (channel->prd_area < B_OK) { TRACE("creating prd_area failed\n"); goto err; diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp index fea24f0720..d0e660fa7a 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp @@ -131,7 +131,8 @@ AHCIController::Init() return B_ERROR; } - fRegsArea = map_mem((void **)&fRegs, addr, size, 0, "AHCI HBA regs"); + fRegsArea = map_mem((void **)&fRegs, addr, size, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, + "AHCI HBA regs"); if (fRegsArea < B_OK) { TRACE("mapping registers failed\n"); return B_ERROR; diff --git a/src/add-ons/kernel/drivers/audio/ac97/geode/geode_controller.cpp b/src/add-ons/kernel/drivers/audio/ac97/geode/geode_controller.cpp index f1f6b84463..90b4b0819f 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/geode/geode_controller.cpp +++ b/src/add-ons/kernel/drivers/audio/ac97/geode/geode_controller.cpp @@ -338,7 +338,7 @@ geode_stream_setup_buffers(geode_stream* stream, const char* desc) stream->buffer_descriptors_area = create_area("geode buffer descriptors", (void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc, - B_32_BIT_CONTIGUOUS, 0); + B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); // TODO: The rest of the code doesn't deal correctly with physical // addresses > 4 GB, so we have to force 32 bit addresses here. if (stream->buffer_descriptors_area < B_OK) { diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp index 5b576f5a35..1d99fdf63e 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp @@ -570,7 +570,8 @@ init_corb_rirb_pos(hda_controller* controller, uint32 quirks) // Allocate memory area controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos", (void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize, - controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, 0); + controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (controller->corb_rirb_pos_area < 0) return controller->corb_rirb_pos_area; @@ -914,7 +915,8 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream, bdl_entry_t* bufferDescriptors; stream->buffer_descriptors_area = create_area("hda buffer descriptors", (void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc, - stream->controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, 0); + stream->controller->is_64_bit ? B_CONTIGUOUS : B_32_BIT_CONTIGUOUS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (stream->buffer_descriptors_area < B_OK) { delete_area(stream->buffer_area); return stream->buffer_descriptors_area; diff --git a/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp b/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp index f3045e9dfb..69bfa66c8a 100644 --- a/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp +++ b/src/add-ons/kernel/generic/ata_adapter/ata_adapter.cpp @@ -414,7 +414,7 @@ ata_adapter_init_channel(device_node *node, // used. prdt_size = (ATA_ADAPTER_MAX_SG_COUNT * sizeof( prd_entry ) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1); channel->prd_area = create_area("prd", (void **)&channel->prdt, B_ANY_KERNEL_ADDRESS, - prdt_size, B_32_BIT_CONTIGUOUS, 0); + prdt_size, B_32_BIT_CONTIGUOUS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (channel->prd_area < B_OK) { res = channel->prd_area; goto err2; diff --git a/src/add-ons/kernel/generic/locked_pool/locked_pool.c b/src/add-ons/kernel/generic/locked_pool/locked_pool.c index 94158f8615..a5d35b0c60 100644 --- a/src/add-ons/kernel/generic/locked_pool/locked_pool.c +++ b/src/add-ons/kernel/generic/locked_pool/locked_pool.c @@ -117,7 +117,7 @@ enlarge_pool(locked_pool *pool, int numBlocks) status = area = create_area(pool->name, (void **)&chunk, B_ANY_KERNEL_ADDRESS, chunkSize, - pool->lock_flags, 0); + pool->lock_flags, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (status < B_OK) { dprintf("cannot enlarge pool (%s)\n", strerror(status)); // TODO: we should wait a bit and try again! diff --git a/src/libs/compat/freebsd_network/bus.cpp b/src/libs/compat/freebsd_network/bus.cpp index 207641b5c2..e6553eb468 100644 --- a/src/libs/compat/freebsd_network/bus.cpp +++ b/src/libs/compat/freebsd_network/bus.cpp @@ -112,8 +112,8 @@ bus_alloc_mem_resource(device_t dev, struct resource *res, pci_info *info, void *virtualAddr; - res->r_mapped_area = map_mem(&virtualAddr, addr, size, 0, - "bus_alloc_resource(MEMORY)"); + res->r_mapped_area = map_mem(&virtualAddr, addr, size, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, "bus_alloc_resource(MEMORY)"); if (res->r_mapped_area < B_OK) return -1; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 2017f8c359..75f058852e 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -5099,9 +5099,7 @@ vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type) /*! This function enforces some protection properties: - kernel areas must be W^X (after kernel startup) - if B_WRITE_AREA is set, B_KERNEL_WRITE_AREA is set as well - - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set - - if no protection is specified, it defaults to B_KERNEL_READ_AREA - and B_KERNEL_WRITE_AREA. + - if B_READ_AREA has been set, B_KERNEL_READ_AREA is also set */ static void fix_protection(uint32* protection) @@ -5113,10 +5111,9 @@ fix_protection(uint32* protection) panic("kernel areas cannot be both writable and executable!"); if ((*protection & B_KERNEL_PROTECTION) == 0) { - if ((*protection & B_USER_PROTECTION) == 0 - || (*protection & B_WRITE_AREA) != 0) - *protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA; - else + if ((*protection & B_WRITE_AREA) != 0) + *protection |= B_KERNEL_WRITE_AREA; + if ((*protection & B_READ_AREA) != 0) *protection |= B_KERNEL_READ_AREA; } }