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

When and where is an MKTME-enabled PTE built in a non-virtualization scenario? #2

@bronzeMe

Description

@bronzeMe
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <keyutils.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
#define sys_encrypt_mprotect 451

void main(void)
{
    char *options_CPU = "algorithm=aes-xts-128 type=cpu";
    long size = PAGE_SIZE;
    key_serial_t key;
    void *ptra;
    int ret;

    /* Allocate an MKTME Key */
    key = add_key("mktme", "testkey", options_CPU, strlen(options_CPU),
                  KEY_SPEC_THREAD_KEYRING);

    if (key == -1) {
        printf("addkey FAILED\n");
        return;
    }
    /* Map a page of ANONYMOUS memory */
    ptra = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
    if (!ptra) {
        printf("failed to mmap");
        goto inval_key;
    }
    /* Encrypt that page of memory with the MKTME Key */
    ret = syscall(sys_encrypt_mprotect, ptra, size, PROT_NONE, key);
    if (ret)
        printf("mprotect error [%d]\n", ret);

    /* Enjoy that page of encrypted memory */

    /* Free the memory */
    ret = munmap(ptra, size);
    sleep(10);

inval_key:
    /* Free the Key */
    if (keyctl(KEYCTL_INVALIDATE, key) == -1)
        printf("invalidate failed on key [%d]\n", key);
}
  • The execution flow of sys_encrypt_mprotect is as follows:

  • (1) SYSCALL_DEFINE4(encrypt_mprotect, unsigned long, start, size_t, len,
    unsigned long, prot, key_serial_t, serial)

  • (2) ret = do_mprotect_ext(start, len, prot, NO_KEY, keyid);

  • (3) error = mprotect_fixup(vma, &prev, nstart, tmp, newflags, keyid, prot & (PROT_TODO));

  • (4) mprotect_set_encrypt(vma, newkeyid, start, end, mprotect_fixup_flags)
    image

  • The mprotect_set_encrypt adds keyid into vm_page_prot

  • When allocating a page for this vma, the function alloc_pages_vma will invoke alloc_pages_vma_keyid, then alloc_pages_vma_keyid invoke __prep_encrypted_page , __prep_encrypted_page adds the keyid into page_ext via lookup_page_ext(page)->keyid = keyid;

  • However, in the non-virtualization scenario, we did not find any function or code that builds an MKTME PTE for this page. Could you give some tips?

  • For virtualization scenario, we find similar operations (`spte |= get_phys_encryption_mask(pfn);') for building mktme ptes in spte.c (arch/x86/kvm/mmu/spte.c)

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