Ton exemple de code linux est extrèment particulier, en gros on voit trainer un int[108] et il écrit en tab[108] car parce qu'il sait parfaitement que le buffer kernel sont en 2^n, donc si tab[107] est valide tab [108] l'est forcément aussi.
Quand tu écris tab[i], le compilo C ne peut pas savoir à tous les coups la taille de tab, pour cela il doit faire une étude global de pointeurs qui n'ira pas forcément loin (paramètre de fonction en int tab[], etc...).
Donc en écrivant tab[i], le compilo comprend prend la base pointé par tab et donne moi le ième élément. Il n'y a aucune notion de taille, et ne te dira jamais rien.
donc tab[i] <=> *(tab+i) (modulo des optimisations possibles)
<=> * (typeof(tab)) ((int)tab + i * sizeof(*tab))
Le segfault ne peut venir que par acces à une mauvaise page mémoire. Les pages système x86, font 4ko. donc si tu alloues 100 octets, tu "un certain nombre" d'octet accessible derrière sans planter. La gestion du malloc empile les bloc mémoires ainsi allouer à la queuelele.
Donc, si tu fais un off by one, tu peux sois écrasé d'autres donnés (super top à debugguer et vive lib efence ou valgrind), soit tomber sur une page interdite et planter.
Le cas du kernel est encore plus violent : il utilise une grosse page de 4Mo : il n'y a _pas_ de protection mémoire dans le kernel.
[^] # Re: Un milliard?!
Posté par Nicolas Boulay (site web personnel) . En réponse au journal 306 bugs dans FreeBSD. Évalué à 3.
Quand tu écris tab[i], le compilo C ne peut pas savoir à tous les coups la taille de tab, pour cela il doit faire une étude global de pointeurs qui n'ira pas forcément loin (paramètre de fonction en int tab[], etc...).
Donc en écrivant tab[i], le compilo comprend prend la base pointé par tab et donne moi le ième élément. Il n'y a aucune notion de taille, et ne te dira jamais rien.
donc tab[i] <=> *(tab+i) (modulo des optimisations possibles)
<=> * (typeof(tab)) ((int)tab + i * sizeof(*tab))
Le segfault ne peut venir que par acces à une mauvaise page mémoire. Les pages système x86, font 4ko. donc si tu alloues 100 octets, tu "un certain nombre" d'octet accessible derrière sans planter. La gestion du malloc empile les bloc mémoires ainsi allouer à la queuelele.
Donc, si tu fais un off by one, tu peux sois écrasé d'autres donnés (super top à debugguer et vive lib efence ou valgrind), soit tomber sur une page interdite et planter.
Le cas du kernel est encore plus violent : il utilise une grosse page de 4Mo : il n'y a _pas_ de protection mémoire dans le kernel.
"La première sécurité est la liberté"