Nenhuma maneira de um processo elevar seus próprios privilégios.
Não há absolutamente nenhum caminho para um processo elevar seus privilégios. Se pudesse, já os teria.
Se um processo tiver o uid real ou salvo elevado, ele poderá copiar esse uid no uid efetivo; Se tiver permitido capacidades, pode copiá-las para o conjunto efetivo, mas deve ter esses privilégios para começar. Você não pode mágica-los fora do ar fin (que bom é um bloqueio que você pode criar uma chave para a vontade).
Então, como você eleva os privilégios no Unix (incluindo o Gnu / Linux)?
(tenha cuidado com isso, apenas para especialistas)
Existem 2 maneiras (tradicionalmente uma, mas ambas são semelhantes e o original pode um dia desaparecer). Para ambos isso acontece quando você chama exec.
(OK eu menti acima, porque depois exec é executado, estamos no mesmo processo, com privilégios alterados, mas executando novo código).
- define o bit setuid e / ou setuid de um arquivo executável: Quando o arquivo é
exec
ed o ID do usuário e / ou o ID do grupo será alterado para o arquivo (possivelmente root), (isso não é uma palavra para linguagens com script na maioria dos Unixes).
- define bits de capacidade de um arquivo executável: Quando o arquivo é
exec
ed, o processo ganhará os recursos definidos no arquivo. Este é agora o método de recomendação.
- Se você estiver convertendo uma raiz seduid, programa para recursos, defina os recursos permitidos conforme necessário e defina o bit efetivo (isso copiará todos os permitidos para efetivo).
- Como você está escrevendo um novo programa, ele pode ser capacitado, portanto, para não definir o bit efetivo, o programa pode copiar e limpar os recursos efetivos conforme necessário (isso reduz o impacto de um bug, incluindo exploits).
Exemplo:
//renice.cc
#include <unistd.h>
#include <sys/capability.h>
class Renice {
cap_t original_cap_state;
cap_t can_nice_cap_state;
cap_value_t cap_list[1];
public:
Renice() {
original_cap_state = cap_get_proc();
if ( original_cap_state == NULL)
/* handle error */;
can_nice_cap_state = cap_get_proc();
if ( can_nice_cap_state == NULL)
/* handle error */;
cap_list[0] = CAP_SYS_NICE;
if (cap_set_flag(can_nice_cap_state, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1)
/* handle error */;
}
~Renice() {
if (cap_free(original_cap_state) == -1 )
/* handle error */;
}
void new_value(int v) {
if (cap_set_proc(can_nice_cap_state) == -1)
/* handle error */;
nice (v);
/* handle error */
if (cap_set_proc(original_cap_state) == -1)
/* handle error */;
}
};
int main () {
Renice renice;
renice.new_value(-1);
nice (-2); //won't work, capability no longer set
sleep (30);
}
- compilar com:
g++ -lcap renice.cc
- definir recursos com:
sudo setcap CAP_SYS_NICE+p a.out
- executado com:
./a.out