5, AG 20215, AG 2021
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Processus
Définition
Modélisation Descripteur État
Création
Destruction
Allocation de ressources
5, AG 20215, AG 2021
Processus UNIX - GNU/Linux Modèle
Création
Terminaison
Recouvrement
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication
Comm. Inter.
chargement d'un fichier exécutable
fork : duplique un processus existant mais ne permet pas de créer un nouveau processus exécutant un nouveau segment de code
Les primitives de la famille exec permettent de remplacer les segments de code,
données et pile par le chargement en mémoire d'un fichier binaire
Le segment système n'est pas modifié l'héritage du fork est donc préservé
Les descripteurs de fichiers, sauf ceux
ouverts avec O_CLOEXEC, sont toujours valides permettant les redirections
5, AG 20215, AG 2021
Communication Comm. Inter.
La primitive de recouvrement : execve
C'est la seule primitive ( fonction exécutée par le système d'exploitation ) permettant de charger un mémoire un fichier binaire
Prototype :
#include <unistd.h>
int execve(const char *filename, char *const argv[ ], char *const envp[ ]);
Cette primitive lorsqu'elle est exécutée par un processus provoque la modification des segments de code, données, pile par le
contenu d'un fichier binaire
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
execve
Les paramètres sont :
filename : nom absolu du fichier binaire
argv : tableau de pointeurs sur des chaînes de caractères qui seront transmises comme argument
envp : tableau de pointeurs sur des chaînes de caractères de la forme variable=valeur
constituant l'environnement du processus
5, AG 20215, AG 2021
Communication Comm. Inter.
execve
La variable PATH est une variable du
SHELL, elle ne peut et n'est pas utilisée pour trouver le fichier binaire dans l'arborescence il est donc obligatoire d'utiliser un nom de fichier absolu
Ce fichier doit être exécutable pour le
propriétaire effectif du processus (droit x) Si ce fichier binaire possède un des bits de prise d'identité du propriétaire ou du groupe positionné les identificateurs de propriétaire ou de groupe effectifs deviennent le
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
execve : résultat retourné
En cas de succès cette primitive ne
revient pas car le segment de code initial est détruit
En cas d'échec execve retourne -1 et
errno contient un code d'erreur indiquant les raisons
5, AG 20215, AG 2021
Communication Comm. Inter.
Caractéristiques du processus résultant
Tous les attributs du processus initial sont préservés
Sauf :
Les signaux pour lesquels le processus
avait placé un gestionnaire sont réinitialisés à leur valeur par défaut (signal)
L'éventuelle pile spécifique pour les gestionnaires de signaux n'est pas conservée (sigaltstack)
Les projections en mémoire ne sont pas
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Caractéristiques du processus résultant
Les segments de mémoire partagée System V sont détachés (shmat)
Les objets de mémoire partagée POSIX sont supprimés (shm_open)
Les descripteurs de files de messages POSIX ouverts sont fermés (mq_overview) Les sémaphores nommés POSIX ouverts sont fermés (sem_overview)
Les temporisations POSIX ne sont pas conservées (timer_create)
Les flux de répertoires ouverts sont fermés (opendir)
5, AG 20215, AG 2021
Communication Comm. Inter.
Caractéristiques du processus résultant
Les verrouillages de mémoire ne sont pas préservés (mlock), mlockall)
Les gestionnaires de terminaison ne sont pas préservés (atexit,on_exit)
L'environnement de travail en virgule flottante est remis à zéro (fenv)
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 1
exécution de ls d'un répertoire ou fichier
dont le nom est passé en paramètre
5, AG 20215, AG 2021
Communication Comm. Inter.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[] ) { char * arg[4];
/* Creation du tableau d'argument */
if ( narg == 1 ) { fprintf(stderr,
"%s : il manque le paramètre le nom du repertoire\n", *argv);
return EXIT_FAILURE;
}
arg[0]="ls";
arg[1]=argv[1];
arg[2]="-l";
arg[3]=NULL;
/* execution de /bin/ls */
execve("/bin/ls", arg, NULL);
perror("execve"); /* execve() ne retourne qu'en cas d'erreur */
return(EXIT_FAILURE);
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 1
5, AG 20215, AG 2021
Communication Comm. Inter.
Exemple 2
erreur sur le nom du fichier
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[] ) { char * arg[4];
/* Creation du tableau d'argument */
if ( narg == 1 ) { fprintf(stderr,
"%s : il manque le paramètre le nom du repertoire\n", *argv);
return EXIT_FAILURE;
}
arg[0]="ls";
arg[1]=argv[1];
arg[2]="-l";
arg[3]=NULL;
/* execution de /bin/ls */
execve("/sbin/ls", arg, NULL);
perror("execve"); /* execve() ne retourne qu'en cas d'erreur */
return(EXIT_FAILURE);
}
Nom de fichier binaire Incorrect
Exemple 2
5, AG 20215, AG 2021
Communication Comm. Inter.
Exemple 2
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 3
bits des prise d'identité
5, AG 20215, AG 2021
Communication Comm. Inter.
Le droit de lecture est
absent
Changer le propriétaire de
l'exécutable ne change rien
Exemple 3
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Ajout du bit de prise d'identité du
pour le propriétaire
Exemple 3
5, AG 20215, AG 2021
Communication Comm. Inter.
Exemple 3
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Utilisation des seteuid et setegid
Définitions :
#include <sys/types.h>
#include <unistd.h>
int seteuid(uid_t euid);
int setegid(gid_t egid);
Ces primitives permettent de positionner les identifiants effectifs déterminant les droits du processus à l'uid ou le gid passé en
paramètre
Résultat retourné : 0 en cas de réussite, -1 en cas d'erreur
5, AG 20215, AG 2021
Communication Comm. Inter.
Utilisation des seteuid et setegid
Pour des raisons de sécurité ces primitives fonctionnent différemment selon que l'uid réel est 0 ( root ) ou différent de 0
uid = 0
sont utilisables pour positionner l'effectif à une valeur quelconque uid ≠ 0
permettent seulement de rendre l'effectif identique au réel
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) {
fprintf(stdout," uid réel=%d\n gid réel=%d\n",getuid(), getgid());
fprintf(stdout,
" uid effectif=%d\n gid effectif=%d\n\n",geteuid(), getegid());
if ( seteuid (2000) < 0 ) { perror("seteuid (2000)");
}
fprintf(stdout," uid réel=%d\n gid réel=%d\n",getuid(), getgid());
fprintf(stdout,
" uid effectif=%d\n gid effectif=%d\n\n",geteuid(), getegid());
if ( seteuid (0) < 0 ) { perror("seteuid (0)");}
fprintf(stdout," uid réel=%d\n gid réel=%d\n",getuid(), getgid());
fprintf(stdout,
" uid effectif=%d\n gid effectif=%d\n\n",geteuid(), getegid());
if ( seteuid (1000) < 0 ) { perror("seteuid (1000)");
}
fprintf(stdout," uid réel=%d\n gid réel=%d\n",getuid(), getgid());
fprintf(stdout,
" uid effectif=%d\n gid effectif=%d\n\n",geteuid(), getegid());
return(EXIT_SUCCESS);
5, AG 20215, AG 2021
Communication Comm. Inter.
Exécution par un utilisateur
dont l'uid est ≠ 0
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
5, AG 20215, AG 2021
Communication Comm. Inter.
Exécution par un utilisateur
dont l'uid est = 0
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
seteuid(2000) réussit même si l'uid 2000 n'existe pas
5, AG 20215, AG 2021
Communication Comm. Inter.
Utilisation du bit de prise d'identité de root
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication
Comm. Inter.
autre utilisateur
Seul setuid(1000) réussit
faisant l'effectif identique au réel
5, AG 20215, AG 2021
Communication
Comm. Inter.
de l'environnement
Le troisième paramètre de la primitive execve est l'environnement passé au processus recouvert
Cet environnement peut-être celui du processus original ou être modifié en
passant en paramètre un tableau de pointeur sur des chaînes de caractères de la forme
variable=valeur
Rappel : le shell transmet à tous ces
processus fils un environnement comportant toutes les variables définies marquées
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Environnement du shell
5, AG 20215, AG 2021
Communication
Comm. Inter.
variable
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Affichage de la valeur d'une variable
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) { char * valeur;
if (narg < 2 ) {
fprintf(stderr,"Il manque le nom de la variable en paramètre\n");
return EXIT_FAILURE ; }
valeur = getenv (argv[1]);
if ( valeur == NULL ){
fprintf(stderr,"Pas de variable %s dans l'environnement\n", argv[1]);
return EXIT_FAILURE ; }
fprintf(stdout,"%s vaut : %s\n",argv[1],valeur);
return EXIT_SUCCESS;
}
5, AG 20215, AG 2021
Communication Comm. Inter.
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 1 : conservation
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) { char * valeur;
char * arg[16];
if (narg < 2 ) {
fprintf(stderr,"Il manque le nom de la variable en paramètre\n");
return EXIT_FAILURE ; }
valeur = getenv (argv[1]);
if ( valeur == NULL ){
fprintf(stderr,"Pas de variable %s dans l'environnement\n", argv[1]);
return EXIT_FAILURE ; }
fprintf(stdout,"%s vaut : %s\n",argv[1],valeur);
/* Execution en conservant l'environnement */
arg[0]="environnement";
arg[1]="SYSTEME";
arg[2]=NULL;
fprintf(stderr,"Execution de ./environnement\n");
execve("./environnement", arg, (char * const*)env);
perror("execve environnement");
return EXIT_FAILURE ;
5, AG 20215, AG 2021
Communication Comm. Inter.
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
A 2015, AG 2021A 2015, AG 2021
Communication
Comm. Inter.
l'environnement
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) { char * valeur;
char * arg[16];
if (narg < 2 ) {
fprintf(stderr,"Il manque le nom de la variable en paramètre\n");
return EXIT_FAILURE ; }
valeur = getenv (argv[1]);
if ( valeur == NULL ){
fprintf(stderr,"Pas de variable %s dans l'environnement\n", argv[1]);
return EXIT_FAILURE ; }
fprintf(stdout,"%s vaut : %s\n",argv[1],valeur);
arg[0]="./environnement";
arg[1]="SYSTEME";
arg[2]=NULL;
/* Suppression de la variable d'environnement */
(void) unsetenv ("SYSTEME");
fprintf(stderr,"Execution de ./environnement\n");
execve("./environnement", arg, (char * const*)env);
perror("execve environnement");
5, AG 20215, AG 2021
Communication
Comm. Inter.
l'environnement
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 3 : création d'un environnement
Le processus exécutant execve peut créer un environnement et le passer au fichier binaire exécuté
Il suffit de créer un tableau de pointeurs sur des chaînes de caractères et le passer en troisième paramètre
5, AG 20215, AG 2021
Communication Comm. Inter.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) { char * valeur;
char * arg[16];
char * envn[]={"SYSTEME=Système d'exploitation",NULL};
if (narg < 2 ) {
fprintf(stderr,"Il manque le nom de la variable en paramètre\n");
return EXIT_FAILURE ; }
valeur = getenv (argv[1]);
if ( valeur == NULL ){
fprintf(stderr,"Pas de variable %s dans l'environnement\n", argv[1]);
} else
fprintf(stdout,"%s vaut : %s\n",argv[1],valeur);
/* Execution en conservant l'environnement */
arg[0]="environnement";
arg[1]="SYSTEME";
arg[2]=NULL;
fprintf(stderr,"Execution de ./environnement\n");
Exemple 3 : création d'un environnement
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 3 : création d'un environnement
5, AG 20215, AG 2021
Communication Comm. Inter.
Exécution d'un programme non binaire
execve permet d'exécuter un programme qui n'est pas le résultat d'une compilation édition de lien ie un « script »
Si le fichier à exécuter commence par une ligne de la forme :
#! interpréteur [argument-optionnel]
interpréteur doit être un fichier exécutable qui sera appelé de la manière suivante :
interpréteur [argument-optionnel] fichier arg...
arg est le second argument de execve
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exécution d'un programme non binaire
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[], char *env[] ) { char * arg[3];
arg[0]="script.sh";
arg[1]="SYSTEME";
arg[2]=NULL;
fprintf(stderr,"Execution d'un script shell\n");
execve("./script.sh", arg, NULL);
perror("execve environnement");
return EXIT_FAILURE ; }
5, AG 20215, AG 2021
Communication
Comm. Inter.
le script : script.sh
#! /bin/bash echo $1
exit 0
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
5, AG 20215, AG 2021
Communication
Comm. Inter.
recouvrement
Elles sont au nombre de 6 que l'on peut séparer en deux groupes
Les fonctions execl* admettant en
paramètres une liste de paramètres de type char * terminées par NULL Les fonctions execv* admettant en
paramètres un tableau de pointeur sur des caractères
Lorsqu'elles se terminent par p la variable PATH de l'environnement est utilisée pour trouver le fichier exécutable
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char
*arg, ...);
int execlp(const char *file, const char
*arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[ ]);
recouvrement : execl*
5, AG 20215, AG 2021
Communication Comm. Inter.
#include <unistd.h>
extern char **environ;
int execv(const char *path, char *const argv[ ]);
int execvp(const char *file, char *const argv[ ]);
int execvpe(const char *file,char *const argv[ ], char *const envp[ ]);
recouvrement
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication
Comm. Inter.
recouvrement
Comme execve toutes ces fonctions ne
retournent pas en cas de succès puisque le segment de code original est remplacé par le segment de code issu du chargement du
fichier binaire
Elles retournent -1 en cas d'erreur errno contient le code d'erreur
perror() peut donc être appelé pour afficher le message d'erreur système
5, AG 20215, AG 2021
Communication Comm. Inter.
Exemple 1 : execlp
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (int narg, char * arg []) { if ( narg == 1 ){
fprintf(stderr, "Il manque le nom du fichier\n");
return EXIT_FAILURE;
}
else {
(void) execlp
("wc", "wc", "-c", "-m", "-l", "-w", *(arg +1), (char * )NULL);
fprintf(stderr, "Echec de la primitive execlp");
return EXIT_SUCCESS ; }
}
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.
Exemple 1 : execlp
5, AG 20215, AG 2021
Communication Comm. Inter.
Exemple 2 : execv
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int narg, char *argv[] ) { char * arg[4];
/* Creation du tableau d'argument */
if ( narg == 1 ) { fprintf(stderr,
"%s : il manque le paramètre le nom du repertoire\n", *argv);
return EXIT_FAILURE;
}
arg[0]="ls";
arg[1]=argv[1];
arg[2]="-l";
arg[3]=NULL;
/* execution de ls avec /bin/ls car execv n'utilise pas PATH */
execv("/bin/ls", arg);
IUT BM J.-L. Anthoine, Arnaud.Giersch@iut-bm.univ-fcomte.fr
2015, AG 2021 2015, AG 2021
Communication Comm. Inter.