我想我必须在某个地方偷偷摸摸,但我看不到哪里,所以多只眼睛可能会有所帮助。
我打算使用linux mremap()在我的VAS中扩大面积。 mremap()调用似乎可以完成这项工作,即新的映射,但是足够使扩展区域无法访问。
这是我的测试程序
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
int main(int c, char **v)
{ char *p;
int i;
setbuf(stdout, NULL);
printf("pid=%d\n",getpid());
p=mmap(0, 4096,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED, -1, 0);
if((void*)p == MAP_FAILED)
{ printf("mmap failed\n");
}
p[0]='a';
printf("p=%#lx p[0]=%c\n",(long)p,p[0]);
printf("Paused [Ret]:"); read(0,&i,4);
p=mremap(p,4096,8192,MREMAP_MAYMOVE);
p[4095]='b';
printf("p=%#lx p[0]=%c p[4095]=%c\n",(long)p,p[0],p[4095]);
printf("Paused [Ret]:"); read(0,&i,4);
p[4096]='c';
printf("p=%#lx p[0]=%c p[4096]=%c\n",(long)p,p[0],p[4096]);
exit(0);
}
运行它得到
PW$ cc -o e e.c
PW$ ./e
pid=7178
p=0x7ffa912b9000 p[0]=a
Paused [Ret]:
此时我可以检查地图
PW$ grep zero /proc/7178/maps
7ffa912b9000-7ffa912ba000 rw-s 00000000 00:01 209101 /dev/zero (deleted)
我们可以看到映射匹配p = 0x7ffa912b9000,继续执行mremap()之后得到的程序
p=0x7ffa9128b000 p[0]=a p[4095]=b
Paused [Ret]:
PW$ grep zero /proc/7178/maps
7ffa9128b000-7ffa9128d000 rw-s 00000000 00:01 209101 /dev/zero (deleted)
在这里,我们可以看到重新映射已完成,我们获得了一个新地址,并且旧数据为'a'还在那里我们还可以看到此新映射的大小为7ffa9128d000-7ffa9128b000-0x2000 = 8192,大小为8192。但是随后尝试在扩展区域中进行书写会带来混乱。
Paused [Ret]:
Bus error (core dumped)
我在Ubuntu 20.04内核上是5.4.0-29-通用的
有一分钟,我以为扩展区可能没有PROT_WRITE,尽管原来有扩展区,所以我在新区域(新地址,新大小)上插入了mprotect()PROT_WRITE | PROT_READ,但没有任何乐趣。] >
[如果有人可以发现钉子并提供新的指针,将不胜感激:)
干杯,披
我想我必须在某个地方偷偷摸摸,但我看不到哪里,所以多只眼睛可能会有所帮助。我打算使用linux mremap()在我的VAS中扩大面积。 mremap()调用似乎可以完成这项工作,即新的映射,但是...
糟糕,一个已知的错误...https://bugzilla.kernel.org/show_bug.cgi?id=8691