首页 > 系统相关 >Memory protection key in Linux

Memory protection key in Linux

时间:2024-02-04 13:25:42浏览次数:29  
标签:WRITE pkey set access protection key Linux ptr

Memory Protection Keys

Reference: MPK in Linux kernel document

Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature which is found on Intel’s Skylake “Scalable Processor” Server CPUs. It will be avalable in future non-server parts.

For anyone wishing to test or use this feature, it is available in Amazon’s EC2 C5 instances and is known to work there using an Ubuntu 17.04 image.

Memory Protection Keys provides a mechanism for enforcing page-based protections, but without requiring modification of the page tables when an application changes protection domains. It works by dedicating 4 previously ignored bits in each page table entry to a “protection key”, giving 16 possible keys.

There is also a new user-accessible register (PKRU) with two separate bits (Access Disable and Write Disable) for each key. Being a CPU register, PKRU is inherently thread-local, potentially giving each thread a different set of protections from every other thread.

There are two new instructions (RDPKRU/WRPKRU) for reading and writing to the new register. The feature is only available in 64-bit mode, even though there is theoretically space in the PAE PTEs. These permissions are enforced on data access only and have no effect on instruction fetches.

Systcalls

There are 3 system calls which directly interact with pkeys:

int pkey_alloc(unsigned long flags, unsigned long init_access_rights)
int pkey_free(int pkey);
int pkey_mprotect(unsigned long start, size_t len,
                  unsigned long prot, int pkey);

Before a pkey can be used, it must first be allocated with pkey_alloc(). An application calls the WRPKRU instruction directly in order to change access permissions to memory covered with a key. In this example WRPKRU is wrapped by a C function called pkey_set().

int real_prot = PROT_READ|PROT_WRITE;
pkey = pkey_alloc(0, PKEY_DISABLE_WRITE);
ptr = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
ret = pkey_mprotect(ptr, PAGE_SIZE, real_prot, pkey);
//... application runs here

Now, if the application needs to update the data at ‘ptr’, it can gain access, do the update, then remove its write access:

pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE
*ptr = foo; // assign something
pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again

Now when it frees the memory, it will also free the pkey since it is no longer in use:

munmap(ptr, PAGE_SIZE);
pkey_free(pkey);

Note

pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. An example implementation can be found in tools/testing/selftests/x86/protection_keys.c.

Behavior

The kernel attempts to make protection keys consistent with the behavior of a plain mprotect(). For instance if you do this:

mprotect(ptr, size, PROT_NONE);
something(ptr);

you can expect the same effects with protection keys when doing this:

pkey = pkey_alloc(0, PKEY_DISABLE_WRITE | PKEY_DISABLE_READ);
pkey_mprotect(ptr, size, PROT_READ|PROT_WRITE, pkey);
something(ptr);

That should be true whether something() is a direct access to ‘ptr’ like:

*ptr = foo;

or when the kernel does the access on the application’s behalf like with a read():

read(fd, ptr, 1);

The kernel will send a SIGSEGV in both cases, but si_code will be set to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when the plain mprotect() permissions are violated.

标签:WRITE,pkey,set,access,protection,key,Linux,ptr
From: https://www.cnblogs.com/holylandofdora/p/18006009

相关文章

  • Bounds checking strategy - mprotect()-based protection - why does not saturate t
    Boundscheckingstrategy-mprotect()-basedprotection-DoesnotsaturatetheCPUlikeothermechanismsSourceSzewczyk,R.,Stonehouse,K.,Barbalace,A.,&Spink,T.(2022).Leapsandbounds:AnalyzingWebAssembly’sperformancewithafocusonboun......
  • edusrc-appkey泄露
    edusrc-appkey泄露简介AppKey泄露是指应用程序的应用密钥(AppKey)或API密钥被非法访问或公开的安全事件。AppKey是应用程序与第三方服务或API进行安全通信的凭证,通常用于身份验证和数据加密。如果这些密钥泄露,攻击者可以利用它们来访问敏感数据、执行未授权的操作或冒充合法的服务......
  • Linux服务器升级GLIBC失败导致shell不可用的问题解决经历
    转自https://blog.csdn.net/u010549608/article/details/126281354?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170696599716800182728626%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170696599716800182728626&biz_i......
  • Linux如何查询是哪些进程占用了端口
    Addressalreadyinuse这个提示,想必大家遇到过,怎么能快速找到问题并解决呢?下面有几种姿势可以了解一下.在对网络连接或特定于应用程序的问题进行故障排除时,首先要检查的事情之一应该是系统上实际使用了哪些端口,以及哪个应用程序正在侦听特定的端口。本文介绍了如何使用netstat,s......
  • Docker笔记(一)docker 在linux里面的安装
    Docker笔记(一)docker在linux里面的安装为什么使用docker(docker理念)在开发环境,将源码+配置+软件等其他项目运行的所有的东西,都打包,直接都给运维,这样运维就不需要自己搭建项目运行的环境了,因为你已经拿到了开发人员本地的全部的东西,相当于拿到开发人员全部的东西,直接在运维那里就......
  • Nexpose v6.6.236 for Linux & Windows - 漏洞扫描
    Nexposev6.6.236forLinux&Windows-漏洞扫描Rapid7VulnerabilityManagement,ReleaseFeb02,2024请访问原文链接:https://sysin.org/blog/nexpose-6/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org您的本地漏洞扫描程序搜集通过实时覆盖整个网络,随......
  • 如何优化Linux服务器的性能和响应速度?
    Linux服务器是一种常用的服务器操作系统,为了保证系统的稳定和高效运行,优化服务器的性能和响应速度显得尤为重要。如何优化Linux服务器的性能和响应速度?1.系统调整内核参数优化:调整Linux内核参数可以提升服务器的性能。例如,通过修改文件/etc/sysctl.conf来设置TCP/IP相关参数,如增......
  • WIP: SLM-DB:Single-Level Key-Value Store with Persistent Memory
    论文原文:https://www.usenix.org/system/files/fast19-kaiyrakhmet.pdf摘要:本文调查了如何利用新出现的可按照字节寻址的持久化内存(PersistentMemory)来增强KV存储的性能。我们充分利用PM,提出了一种新型的KV存储,SLM-DB,这种存储同时利用到了B+树索引和LSM-tree的优点。我们提出......
  • Linux调度pick_next_task_fair整体框架解读
    pick_next_task_fair是CFS调度类中选择next任务的主要路径,其主要功能是从当前CPU的就绪队列cfs_rq中选出一个可运行的任务作为"next任务",并将前一个任务prev重新放到就绪队列。 下面是这段代码框架流程解读。1判断rq->cfs.nr_running>0?如果不满足说明没有可运行任务则gotoidl......
  • linux清理磁盘空间
    根目录/仍然使用了100%的空间,可能会导致系统运行受阻。可以尝试以下方法来释放根分区的空间:删除不需要的文件:检查根目录中是否有不必要的文件或目录,并删除它们以释放空间。清理日志文件:检查/var/log/目录中是否有大型日志文件,并根据需要删除或归档它们。清理软件......