Ho un task_struct *
che ho ricevuto chiamando lo find_task_by_vpid(get_pid())
. Mi piacerebbe capire quale utente possiede quel processo in modo che possa fare un controllo dei permessi nella chiamata di sistema che sto scrivendo, ma osservare il codice sorgente task_struct
non ha aiutato molto. L'unica cosa che è sembrata utile è la loginuid
, ma per qualche motivo il kernel non verrà compilato se provo ad accedervi in questo modo: my_task_struct->loginuid
. C'è un altro modo per ottenere l'utente che ha chiamato il processo dallo task_struct
?C'è un modo per scoprire quale utente possiede un processo dal task_struct del processo?
risposta
Sfortunatamente, gli ID utente/gruppo non vengono più memorizzati nella struttura dell'attività, ma in una struttura di privilegi separata che viene allocata e condivisa dinamicamente tra tutte le attività che hanno gli stessi ID. Questo a sua volta crea una situazione in cui setuid
può fallire a causa di esaurimento risorse, e il fallimento di setuid
per sostenere i privilegi è una fonte infame di vulnerabilità ...
ogni caso, è in questi membri della task_struct
:
const struct cred __rcu *real_cred; /* objective and real subjective task
* credentials (COW) */
const struct cred __rcu *cred; /* effective (overridable) subjective task
* credentials (COW) */
Grazie davvero. sai come inizializzare dove inizializzato quel user_struct? – saman
@saman: Non è giusto, ma vai a cercare il codice per 'setuid()' ecc. E dovresti vedere alcuni esempi di come è stato fatto. –
@R .. Posso solo trovare la dichiarazione della chiamata di sistema setuid in unistd.h ma non riesco a trovare l'implementazione di questa chiamata di sistema [qui] (http://stackoverflow.com/questions/27594865/add-another -field-to-user-struct) è la mia domanda puoi rispondere? – saman
Per accedere a un ID utente (UID) all'interno dello spazio del kernel si può fare qualcosa secondo le seguenti linee (a partire da Linux 4.9.13):
struct task_struct *task;
for_each_process(task) {
uid_t uid = __kuid_val(task_uid(task));
}
task_uid
restituisce una struttura chiamato kuid_t
e per accedere al valore effettivo è necessario chiamare __kuid_val
o accedervi direttamente (task_uid(task).val
).
In alternativa, è possibile utilizzare from_kuid(&init_user_ns, task_uid(task))
.
Guarda l'implementazione di 'geteuid'. Per i controlli dei permessi, però, quasi certamente si desidera utilizzare il framework generale esistente per quel tipo di cose piuttosto che creare la propria logica che è incoerente con il resto del sistema. – zwol
Io uso 'geteuid()' per ottenere l''euid' dell'utente che ha chiamato la chiamata di sistema, ma non sono sicuro di come usarlo per ottenere' uid' (o 'euid') del' task_struct' per il 'pid' passato nella chiamata di sistema stessa. – Mason