2016-04-05 22 views
8

Sotto Android 4, il seguente semplice riga di codice nativo C fallisce con un errore Permission deniedquando non Esegui come root:cosa può causare un errore socket() "Autorizzazione negata"?

online_socket = socket(AF_INET, SOCK_DGRAM, 0); 

ho fare hanno root accesso al dispositivo, ma vogliono per eseguire il processo come utente non privilegiato.

Si noti che l'errore si verifica anche prima del binding del socket.

Immagino ci sia qualche impostazione di sicurezza che deve essere modificata? Qualcuno può dirmi dove cercare?

In questo caso, l'O/S è davvero Android, ma suppongo che il problema sia realmente legato a Linux (poiché Android è basato su un kernel Linux).

Per coloro che si chiedono: questo è un programma personalizzato eseguito in un'installazione completa() di Debian Jessie in esecuzione in un ambiente Android 4.

Aggiornamento

ho imparato che il kernel Android ha uno speciale CONFIG_ANDROID_PARANOID_NETWORK estensione che consente l'accesso alla rete solo agli utenti in AID_INET e AID_NET_RAW gruppi.

Tuttavia, anche dopo aver aggiunto l'utente a questi gruppi, socket() è ancora respinto (e ping sembra avere lo stesso problema, BTW).

uid=5(imp) gid=51(imp) groups=51(imp),3003(aid_inet),3004(aid_net_raw),3005(aid_admin),3001(aid_bt),3002(aid_bt_net) 

Non posso dire se questo CONFIG_ANDROID_PARANOID_NETWORK flag è impostato in questo particolare Kernel, come io non ho accesso al file di configurazione.

Update 2

ho scoperto che sia roote anche il mio utente non privilegiato imp può infatti chiamare con successo socket() - almeno con la messa a punto i gruppi di cui sopra.

Tuttavia, chiamando lo stesso processo di root e poi passare a imp usando la chiamata di sistema seteuid() impedisce socket() da riuscire. Qualche idea?

+0

non ottengo un errore sotto Arch Linux su un computer portatile x68_64. Sospetto che questa sia una cosa di Android. –

+0

Hai provato a utilizzare un protocollo diverso da "0" (terzo parametro)? Ad esempio: 6 per tcp o 17 per udp? In realtà, sarà necessario utilizzare il protocollo 17 per un socket Datagram udp. –

+0

@gerhardd. - Ho appena provato a cambiare il protocollo a 17, ma sfortunatamente questo non aiuta. Non dovrei che il programma in questione funzioni bene in un certo numero di altre piattaforme * non-Android * con Kernel che vanno dal 2.4 al 4.4 –

risposta

10

Come risulta, Android utilizza una speciale patch del kernel che viene attivata con CONFIG_ANDROID_PARANOID_NETWORK. Questa patch consente l'accesso alla rete agli utenti del sistema che appartengono a determinati gruppi speciali con ID hardcoded.

groupadd -g 3001 aid_bt 
groupadd -g 3002 aid_bt_net 
groupadd -g 3003 aid_inet 
groupadd -g 3004 aid_net_raw 
groupadd -g 3005 aid_admin 

Ecco perché Android aggiunge normalmente gli utenti (vale a dire applicazioni) per questi gruppi solo quando l'applicazione specifica dispone di autorizzazioni di rete.

Aggiunta di un utente a questi gruppi dà il permesso di utilizzare socket() come descritto nella domanda:

usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin someuser 

Tuttavia, quando un processo utilizza seteuid() passare da root a un utente normale (ad esempio someuser), quindi non è sufficiente (o probabilmente irrilevante) che questo utente effettivo abbia l'appartenenza al gruppo aid_*. Al contrario, l'utente deve essere esplicitamente root un membro di questi gruppi:

usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin root 

Questo risolto il problema per me.

Nota che ho anche provato a giocare con setegid() e simile come alternativa, ma niente di tutto questo ha aiutato ...

+0

Questo funziona per me. – Geofferey