Por que em alguns sistemas max uid / gid é 65534 um não 65535?

2

Eu sei que não há um valor máximo compartilhado para uid (ou gid): alguns sistemas usam 99 (Slackware, ...), outros 65534 (Debian, ...).
Eu pergunto se existe uma motivação específica para usar 65534 e não 65535 (0xFFFF). Obrigado.

    
por user2431763 24.01.2014 / 13:10

3 respostas

5

Se o UID máximo for 65535, não haverá nenhum valor para indicar um erro ou um UID desconhecido se o UID estiver armazenado em um valor não assinado de 16 bits.

    
por 24.01.2014 / 13:27
4

Por que 99?

Isso não é na verdade um máximo. É um limite, onde os IDs das contas "do sistema" param e os IDs das contas "pessoa real" são iniciados. É bastante arbitrário e variável também. Não há razão real para que seja 99, exceto que 100 é um número redondo acessível.

É um número redondo acessível acordado pelas várias ferramentas de gerenciamento de banco de dados de senha e grupo para uma plataforma. No Debian versão 7, por exemplo, as ferramentas useradd e groupadd procuram /etc/login.defs para os intervalos de UIDs e GIDs que contam como "sistema" e "usuário", e o último intervalo é de 1000 a 60000 para ambos UIDs e GIDs.

Por que 65534?

Primeiro, porque existem duas convenções generalizadas nas chamadas do sistema POSIX:

  • Um valor de retorno de -1 (convertido para o tipo de retorno) indica um erro, com o número do erro disponível na macro errno .
  • Um valor de entrada de -1 indica "não muda".

Estas não são convenções universais . Observe que não há possibilidade de um erro retornar da chamada do sistema geteuid() , por exemplo. (Processos sempre têm UIDs efetivos.) Portanto, não há static_cast<uid_t>(-1) para se preocupar com isso. Mas pelo menos um deles se aplica a UIDs e GIDs. No sistema setreuid() e setregid() , um argumento de -1 significa "sem alteração". Portanto, static_cast<uid_t>(-1) e static_cast<gid_t>(-1) não são utilizáveis adequadamente como IDs reais.

Em segundo lugar, porque os UIDs e os GIDs no Linux costumavam ser de 16 bits.

Isso mudou para 32 bits na virada do século, mas seus ecos continuam vivos, e na verdade é mais sutil do que parece à primeira vista. -1 convertido para um inteiro não assinado de 16 bits, que é o que costumava ser uid_t e gid_t (na interface de chamada do sistema), é claro 65535 como você observou. Então, isso não era um UID ou um GID utilizável.

No entanto, para os benefícios dos programas que usavam a API de 16 bits nos kernels que tinham alternado para% de 32 bitsuid_t e gid_t , o Linux definiu um "UID de estouro" e um "GID de estouro". Isso ocorreu porque em vários pontos houve algumas interações bastante desagradáveis devido ao lançamento feito entre 16 bits e 32 bits. Os programas de 16 bits viam o UID 65536 como o superusuário quando o kernel não. Os kernels mais antigos viam o UID 131072 como o superusuário quando o código das aplicações não o fazia.

O "overflow UID" e "overflow GID" essencialmente mapearam todos os UIDs e GIDs de 32 bits maiores que 65535 para 65534 para o código de 16 bits. Isso significa que um valor segundo , 0xFFFE, agora estava inutilizável como um valor real de UID ou GID.

E, é claro, -1 convertido para o tipo de UID e GID de 32 bits também não pode ser usado.

    
por 24.01.2014 / 22:34
0

Os sistemas normalmente reservam o valor inteiro mais alto sem sinal 0xffff (ou -1 se o valor for interpretado como um inteiro com sinal) para indicar "inválido" ou "não usado". (0xffff é de 16 bits, é claro. Alguns sistemas usam 0xffffffff de 32 bits.)

Zero não pode ser usado para isso, porque é reservado para uso raiz.
(Reservar 0 para root é, se bem me lembro, uma convenção POSIX que é observada por quase todos os outros sistemas operacionais também, por razões de compatibilidade).

    
por 24.01.2014 / 13:45

Tags