/* Copyright (C) 2008 Emmanuel Varoquaux
This file is part of XOS.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
#include
#include
#include
extern char end;
const char blabla[] = "blabla"; /* section .rodata */
static void f()
{
char buf[100000];
*buf = 1;
}
static int do_exception(int n)
{
void *_brk, *new_brk;
/* Chacune des sequences doit provoquer une exception. La variable n execute
une sequence particuliere. */
switch (n) {
case 1: /* ecriture dans une zone memoire en lecture seule */
printf("crashing...\n"); /* pour controler que le segfault se produit bien la ou on l'attend */
asm volatile ("movb $0, blabla");
break;
case 2: /* autre ecriture dans une zone memoire en lecture seule */
printf("crashing...\n");
asm volatile ("movb $0, _start");
break;
case 3: /* ecriture dans une zone memoire inaccessible */
printf("crashing...\n");
asm volatile ("movb $0, 0");
break;
case 4: /* test sbrk 1 */
_brk = sbrk(0);
new_brk = brk;
if ((unsigned long)new_brk & 0xfff) {
new_brk = (void *)((unsigned long)new_brk & 0xfffff000);
new_brk += 4096;
}
sbrk(new_brk - _brk);
_brk = sbrk(0);
*(char *)(_brk - 1) = '\0'; /* pas de segfault */
printf("crashing...\n");
*(char *)_brk = '\0'; /* segfault */
break;
case 5: /* test sbrk 2 */
sbrk(4096);
_brk = sbrk(0);
if ((unsigned long)_brk & 0xfff) {
_brk = (void *)((unsigned long)_brk & 0xfffff000);
_brk += 4096;
}
*(char *)(_brk - 1) = '\0'; /* pas de segfault */
printf("crashing...\n");
*(char *)_brk = '\0'; /* segfault */
break;
case 6: /* ecriture dans une zone memoire en lecture seule par un appel systeme */
printf("crashing...\n");
if (read(0, (void *)(unsigned long)blabla, 1) < 0) {
printf("segmentation fault segfault\n");
_exit(1);
}
break;
case 7: /* autre ecriture dans une zone memoire en lecture seule par un appel systeme */
printf("crashing...\n");
read(0, (void **)f, 1);
break;
default:
return 0;
}
printf("An exception should have occured !\n");
return 1;
}
int main()
{
int n;
int pid;
for (n = 1; n <= 6; n++) {
printf("Test: %d\n", n);
if (!(pid = fork())) {
do_exception(n);
_exit(1);
}
waitpid(pid, NULL, 0);
printf("\n");
}
/* accroissement de la taille de la pile - ne devrait pas produire d'erreur justement */
f();
printf("ok !\n");
return 0;
}