IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

'gets' est-il dangereux ?


Sujet :

C

  1. #1
    Rédacteur
    Avatar de pi-2r
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2006
    Messages
    1 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 486
    Points : 2 440
    Points
    2 440
    Par défaut 'gets' est-il dangereux ?
    Bonjour,


    lors d'un Tp en programmation, je suis amené à utiliser la fonction 'gets()'.
    étant sous Linux, j'utilise le compilateur gcc (gcc -Wall -o prog prog.c).
    Lors de la compilation, j'obtiens l'avertissement suivant:
    maj.c.text+0x25): warning: the `gets' function is dangerous and should not be used.
    MOn prof n'arrive pas à dire pourquoi cela est dangereux....

    Si quelqu'un le sait ?

    Merci d'avance

  2. #2
    Membre averti Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Points : 339
    Points
    339
    Par défaut
    Parce que gets() travaille avec un buffer interne pour lire le clavier. Comme la taille de ce buffer n'est pas connue ni contrôlée, il est possible de le faire déborder (en lui soumettant une très très longue chaine) et de créer une attaque par débordement de buffer.

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926

  4. #4
    Rédacteur
    Avatar de pi-2r
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2006
    Messages
    1 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 486
    Points : 2 440
    Points
    2 440
    Par défaut
    merci pour vos réponse

    Lors de la discution avec mon prof j'avais soulevé l'idée des attaques par "buffer overflow",mais il me soutenait que cela n'était pas possible et que c'était mon compilateur qui ne marché pas bien.......

  5. #5
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 078
    Points : 2 334
    Points
    2 334
    Par défaut
    ...

    Encore un prof qui ne maitrise pas son sujet, mais qui par un orgeuil mal placé ou démesuré n'admetra pas que l'etudiant puisse lui apprendre quelque chose.

    Un bon conseil, ne prend surtout pas pour argent comptant ce qui sort de sa bouche si tu souhaite continuer a coder et de surcroit si tu souhaite coder proprement.

    Bon courage pour la suite, je sais ce que c'est d'avoir ce genre de prof.

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 884
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 884
    Points : 219 331
    Points
    219 331
    Billets dans le blog
    123
    Par défaut
    Surtout que c'est un truc que le compilo dit (genre il ne faut pas croire gcc, ou même celui de Visual), et que en plus, c'est marqué dans la page de man de la fonction. (La section que je préfère qui s'appelle BUGS).
    D'ailleurs, c'est grace au man que j'ai appris que l'on ne devait pas l'utilisé . Comme quoi, toujours lire une doc, entièrement .

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    genre il ne faut pas croire gcc, ou même celui de Visual
    Sur ce point là quand même, c'est vrai qu'il ne faut pas croire tout ce que Visual dit .

    c'est marqué dans la page de man de la fonction
    Et aussi dans la norme. Personnellement, je préfère toujours lire la norme plutôt que les man pages ou MSDN Library quand il s'agit de fonctions/fonctionnalités standard. Mais c'est vrai que les man pages et MSDN Library ça s'ouvre en un clin d'oeil alors que pour consulter la norme il faut un peu faire une descente dans son disque dur, à moins d'avoir déjà défini des raccourcis claviers comme moi je l'ai fait (Ctrl + Alt + Shift + C => Std C ).

  8. #8
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Citation Envoyé par Melem Voir le message
    Sur ce point là quand même, c'est vrai qu'il ne faut pas croire tout ce que Visual dit .
    On peut dire pareil de GCC

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Franchement, j'ai vu plus de dépréciation fallacieuses sous Visual 2005+ que sous gcc...

    D'un autre côté, il y a moyen d'utiliser gets() plus ou moins en sécurité. Seulement... pas en C standard.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    #include <windows.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
     
    DWORD GetPageSize(void)
    {
    	SYSTEM_INFO si = {0};
    	GetSystemInfo(&si);
    	return si.dwPageSize;
    }
     
    size_t GetSizeInPagesEx(size_t sizeInBytes, size_t cbPageSize)
    {
    	return ((sizeInBytes + cbPageSize-1) / cbPageSize);
    }
     
    #if 0
    size_t GetSizeInPages(size_t sizeInBytes)
    {
    	return GetSizeInPagesEx(sizeInBytes, GetPageSize());
    }
    #endif
     
    /*
    Fonction qui utilise les allocations bas niveau de Windows
    pour appeler gets() en toute sécurité.
    */
    int super_gets(char *szDestBuffer, size_t cchDestSize)
    {
    	int ret = -1;
    	/* Calcul des tailles: On réserve une page de plus que nécessaire,
    	   pour avoir une page de protection. */
    	DWORD const cbPageSize = GetPageSize();
    	size_t const cbDestSize = cchDestSize * sizeof *szDestBuffer;
    	size_t const sizeInPages = GetSizeInPagesEx(cbDestSize, cbPageSize);
    	size_t const cbSizeWithoutGuardPage = sizeInPages * cbPageSize;
    	size_t const cbFullSize = (sizeInPages+1) * cbPageSize;
     
    	/* Note: Ici, ça marche aussi avec PAGE_READWRITE, 
    	   donc toute tentative d'accès à une mémoire non-committée provoque une exception.
    	   Mais je trouve que PAGE_NOACCESS est plus explicite. */
    	void* pFullBuffer = VirtualAlloc(NULL, cbFullSize, MEM_RESERVE, PAGE_NOACCESS);
    	if(pFullBuffer != NULL)
    	{
    		void *pCommitted = VirtualAlloc(pFullBuffer, cbSizeWithoutGuardPage, MEM_COMMIT, PAGE_READWRITE);
    		if(pCommitted != NULL)
    		{
    			/* On écrit juste avant la page de protection, 
    			   comme ça si on dépasse, une exception est lancée. */
    			unsigned char * pbyBuf = pCommitted;
    			assert(pCommitted == pFullBuffer);
    			pbyBuf += cbSizeWithoutGuardPage;
    			pbyBuf -= cbDestSize;
     
    			{
    				void * const pBuf = pbyBuf;
    				char * szBuf = pBuf;
    				int bOverflow = 0;
    				size_t cchTypedLength;
     
    				/* On appelle gets() et on attrape l'exception en cas de dépassement */
    				__try
    				{
    					#pragma warning(push)
    					#pragma warning(disable:4996) /*désactive le warning sur gets()*/
    					gets(szBuf);
    					#pragma warning(pop)
    				}
    				__except((GetExceptionCode()==EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH))
    				{
    					bOverflow = 1;
    				}
     
    				if(bOverflow)
    				{
    					/* Il y a eu dépassement: On écrit toute la longueur du buffer. */
    					cchTypedLength = cchDestSize-1;
    					szBuf[cchTypedLength] = '\0';
    				}
    				else
    				{
    					/* Il n'y a pas eu dépassement: On écrit juste la taille demandée. */
    					cchTypedLength = strlen(szBuf);
    				}
     
    				assert(cchTypedLength < cchDestSize);
    				memcpy(szDestBuffer, szBuf, (cchTypedLength+1) * sizeof *szBuf);
    				ret = 0;
    			}
    		}
     
    		VirtualFree(pFullBuffer, 0, MEM_RELEASE), pFullBuffer=NULL;
    	}
    	return ret;
    }
     
    void TestGets(void)
    {
    	int magic1 = 0x12345678;
    	char buf[8];
    	int magic2 = 0x5678ABCD;
     
    	puts("Entrer une chaine :");
    	super_gets(buf, ARRAYSIZE(buf));
     
    	assert(magic1 == 0x12345678);
    	assert(magic2 == 0x5678ABCD);
    	printf("Chaine entree : \"%s\" - Longueur : %lu.\n", buf, (unsigned long)strlen(buf));
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Upload d'avatars est ce dangereux?
    Par zintelix3d dans le forum Sécurité
    Réponses: 9
    Dernier message: 12/08/2008, 17h14
  2. Réponses: 10
    Dernier message: 13/10/2007, 13h17
  3. Réponses: 2
    Dernier message: 10/10/2007, 18h03
  4. [Sécurité] Le client/serveur est il dangereux ?
    Par kisitomomotene dans le forum Débats sur le développement - Le Best Of
    Réponses: 19
    Dernier message: 18/09/2007, 00h22
  5. Réponses: 7
    Dernier message: 18/03/2007, 02h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo