Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Unable to set ACCESSING_USER_MEM in access_user_memory #61

@Anekoique

Description

@Anekoique

I encountered this problem when implementing lazy allocation of file pages. When the kernel tries to access the contents of the user-unallocated page, it cannot properly identify it as coming from the user, resulting in a failure to trigger a page fault normally.

fn check_null_terminated<T: PartialEq + Default>(
    start: VirtAddr,
    access_flags: MappingFlags,
) -> LinuxResult<usize> {
    let align = Layout::new::<T>().align();
    if start.as_usize() & (align - 1) != 0 {
        return Err(LinuxError::EFAULT);
    }

    let zero = T::default();

    let mut page = start.align_down_4k();

    let start = start.as_ptr_of::<T>();
    let mut len = 0;

    access_user_memory(|| {
        loop {
            if is_accessing_user_memory() {
                // debug!("is_accessing_user_memory");
                panic!("is_accessing_user_memory");
            }
            // SAFETY: This won't overflow the address space since we'll check
            // it below.
            let ptr = unsafe { start.add(len) };
            while ptr as usize >= page.as_ptr() as usize {
                // We cannot prepare `aspace` outside of the loop, since holding
                // aspace requires a mutex which would be required on page
                // fault, and page faults can trigger inside the loop.

                // TODO: this is inefficient, but we have to do this instead of
                // querying the page table since the page might has not been
                // allocated yet.
                let task = current();
                let aspace = task.task_ext().process_data().aspace.lock();
                if !aspace.check_region_access(
                    VirtAddrRange::from_start_size(page, PAGE_SIZE_4K),
                    access_flags,
                ) {
                    return Err(LinuxError::EFAULT);
                }

                page += PAGE_SIZE_4K;
            }

            // This might trigger a page fault
            // SAFETY: The pointer is valid and points to a valid memory region.
            if unsafe { ptr.read_volatile() } == zero {
                break;
            }
            len += 1;
        }
        Ok(())
    })?;

    Ok(len)
}

In the above situation, Starry cannot panic.
But the strange thing is that if I uncomment debug! or add a line of debug! it can panic normally again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions