eu fiz sudo cat /proc/1/maps -vv
Estou tentando entender a saída. Posso ver muitas bibliotecas compartilhadas sendo mapeadas para o segmento de mapeamento de memória conforme o esperado.
7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220 /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220 /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220 /lib/x86_64-linux-gnu/libnih.so.1.0.0
No final, há algo como
7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0 [heap]
7fff97863000-7fff97884000 rw-p 00000000 00:00 0 [stack]
7fff97945000-7fff97946000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
O que significa vdso
e vsyscall
significa? vsyscall é a parte do kernel da memória? Seria ótimo se alguém pudesse lançar alguma luz sobre o assunto.
Respostas:
Os vsyscall e vDSO segmentos são dois mecanismos utilizados para acelerar certas chamadas de sistema em Linux. Por exemplo,
gettimeofday
geralmente é invocado por meio desse mecanismo. O primeiro mecanismo introduzido foi vsyscall , que foi adicionado como uma forma de executar chamadas de sistema específicas que não precisam de nenhum nível real de privilégio para serem executadas a fim de reduzir a sobrecarga de chamadas do sistema. Seguindo o exemplo anterior, tudo o quegettimeofday
precisa fazer é ler a hora atual do kernel. Existem aplicativos que chamam comgettimeofday
frequência (por exemplo, para gerar carimbos de data / hora), a ponto de se preocupar com até mesmo um pouco de sobrecarga. Para resolver essa questão, o kernel mapeia no espaço do usuário uma página contendo a hora atual e umgettimeofday
implementação (ou seja, apenas uma função que lê o tempo economizado em vsyscall ). Usando esta chamada de sistema virtual, a biblioteca C pode fornecer um rápidogettimeofday
que não tem a sobrecarga introduzida pela alternância de contexto entre o espaço do kernel e o espaço do usuário normalmente introduzido pelo modelo de chamada de sistema clássicoINT 0x80
ouSYSCALL
.No entanto, este mecanismo vsyscall tem algumas limitações: a memória alocada é pequena e permite apenas 4 chamadas de sistema, e, mais importante e sério, a página vsyscall é alocada estaticamente para o mesmo endereço em cada processo, uma vez que a localização da página vsyscall é pregado na ABI do kernel. Esta alocação estática do vsyscall compromete o benefício introduzido pela randomização do espaço de memória comumente usada pelo Linux. Um invasor, após comprometer um aplicativo explorando um estouro de pilha, pode invocar uma chamada de sistema do vsyscallpágina com parâmetros arbitrários. Tudo que ele precisa é o endereço da chamada do sistema, que é facilmente previsível, pois é alocado estaticamente (se você tentar executar novamente o seu comando mesmo com aplicativos diferentes, você notará que o endereço do vsyscall não muda). Seria bom remover ou pelo menos randomizar a localização da página vsyscall para impedir esse tipo de ataque. Infelizmente, os aplicativos dependem da existência e do endereço exato dessa página, portanto, nada pode ser feito.
Esse problema de segurança foi resolvido substituindo todas as instruções de chamada do sistema em endereços fixos por uma instrução trap especial. Um aplicativo que tenta chamar a página vsyscall fará uma armadilha no kernel, que então emulará a chamada de sistema virtual desejada no espaço do kernel. O resultado é uma chamada de sistema kernel emulando uma chamada de sistema virtual que foi colocada lá para evitar a chamada de sistema kernel em primeiro lugar. O resultado é um vsyscall que leva mais tempo para ser executado, mas, o que é crucial, não quebra a ABI existente. Em qualquer caso, a lentidão só será vista se o aplicativo estiver tentando usar a página vsyscall em vez do vDSO .
O vDSO oferece a mesma funcionalidade do vsyscall, enquanto supera suas limitações. O vDSO (Virtual Dynamically linked Shared Objects) é uma área de memória alocada no espaço do usuário que expõe algumas funcionalidades do kernel no espaço do usuário de maneira segura. Isso foi introduzido para solucionar as ameaças à segurança causadas pelo
vsyscall
. O vDSO é alocado dinamicamente, o que resolve questões de segurança e pode ter mais de 4 chamadas de sistema. Os links vDSO são fornecidos por meio da biblioteca glibc. O vinculador será vinculado à funcionalidade glibc vDSO , desde que tal rotina tenha uma versão vDSO que a acompanha , comogettimeofday
. Quando seu programa é executado, se seu kernel não tem vDSO suporte, um syscall tradicional será feito.Créditos e links úteis:
fonte
Eu só quero adicionar que agora em novos kernels,
vDSO
não é usado apenas para syscalls "seguros", mas é usado para decidir qual mecanismo syscall é o método preferido para invocar um syscall no sistema.fonte