Isso não é um absurdo, existe uma maneira legítima de fazer isso no Linux e suas expectativas são errôneas.
As cadeias de caracteres de argumento e ambiente transmitidas ao código de inicialização de um programa pelo kernel são armazenadas na memória virtual do espaço de aplicativo comum, exatamente como qualquer outro dado do programa; e, assim como qualquer outra variável de dados do programa, elas são modificáveis. É bastante legítimo que os programas os modifiquem.
(Note que isto é do ponto de vista do que o kernel fornece e aplica. O que os padrões para linguagens de programação particulares podem dizer não é necessariamente o mesmo. Mas no que diz respeito ao kernel, é apenas uma área de memória virtual do espaço de aplicação para dados do programa legíveis e graváveis.O kernel não se importa com a linguagem de programação da qual você compilou o seu código de máquina.)
O arquivo /proc/${PID}/environ
é apenas uma janela para essa memória virtual do espaço do aplicativo. Em vez de lembrar os dados reais do ambiente do processo, o Linux apenas lembra os endereços iniciais e finais da área de ambiente com a qual iniciou o processo, e o arquivo /proc/${PID}/environ
apenas lê o que está nessa memória agora. Você não deve esperar que este arquivo contenha uma lista de strings terminadas em ␀. Essa é uma expectativa errônea.
Não há nenhuma função da biblioteca GNU C para modificar a memória que contém essas cadeias. Mas vários programas têm suas próprias funções para fazer isso.
Por exemplo, considere o OpenSSH. O servidor OpenSSH modifica o que o ps
mostra para seu vetor argumento, para ler coisas como sshd: JdeBP [priv]
.
O servidor OpenSSH contém código que tenta imitar no Linux o que ele pode fazer com a biblioteca BSD C no OpenBSD. No OpenBSD há uma função de biblioteca BSD C chamada setproctitle()
que reescreve o vetor de argumento do processo conforme relatado pelo comando ps
. Ele chama sysctl()
para passar um novo vetor argumento para o kernel, que ps
pode ler com sysctl()
. O FreeBSD tem uma função similar.
No Linux, como explicado, o kernel não lembra de argumentos e ambiente reais, apenas os endereços de início e fim das áreas de memória onde inicialmente os colocaram ao iniciar o processo. Portanto, a porta Linux do OpenSSH tem uma função setproctitle()
de compatibilidade que substitui a área de memória mencionada anteriormente.
Esta função de compatibilidade calcula o tamanho total da área de ambiente e da área de argumento, e sobrescreve tudo isso com a nova cadeia de argumento. Isso ocorre porque, no caso normal, os programas que chamam setproctitle()
desejam gravar em um conjunto mais longo de dados de argumentos do que o processo original. sshd
geralmente faz. Por isso, permite que os novos argumentos sobrescrevam a área do ambiente que segue a área de argumento, dando aos programas mais espaço para conjuntos mais longos de cadeias de argumentos.
Importante, ele também preenche a parte não usada da área que não precisou ser sobrescrita, com o tamanho original do argumento total e dados do ambiente, com ␀s.
E o que você está vendo é o resultado exato disso. Se você encontrar um processo do servidor OpenSSH em seu sistema, verá que ele também possui muitos ins em seu /proc/${PID}/environ
.
Leitura adicional
-
setproctitle
. Manual do FreeBSD 11.0. -
setproctitle
. Manual do OpenBSD. -
setproctitle()
. OpenSSH Portable Release. -
environ_read()
. fs / proc / base. Kernel do Linux. Elétrons Livres.