xref: /minix/minix/lib/libmagicrt/magic_asr.c (revision e1cdaee1)
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <magic_def.h>
5 #include <magic_mem.h>
6 #include <magic_asr.h>
7 #include <magic.h>
8 
9 #ifdef __MINIX
10 static unsigned long magic_rand_next;
11 static void magic_srand(unsigned int seed)
12 {
13     magic_rand_next = (unsigned long) seed;
14 }
15 
16 static int magic_rand()
17 {
18     magic_rand_next = magic_rand_next * 1103515245 + 12345;
19     return (int)(magic_rand_next % ((unsigned long)RAND_MAX + 1));
20 }
21 static int magic_rand_seed()
22 {
23     int x;
24     return (int)&x + (int)&magic_rand_seed;
25 }
26 #else
27 #define magic_srand     srand
28 #define magic_rand      rand
29 #define magic_rand_seed() time(0)
30 #endif
31 
32 #define MINIMUM_PADDING 1
33 
34 PUBLIC int magic_asr_get_padding_size(int region) {
35     int padding = 0;
36 
37     switch(region) {
38         case MAGIC_STATE_HEAP | MAGIC_ASR_FLAG_INIT:
39             if(_magic_asr_heap_max_offset){
40                 padding = (magic_rand() % _magic_asr_heap_max_offset) + MINIMUM_PADDING;
41             }
42             break;
43         case MAGIC_STATE_HEAP:
44             if(_magic_asr_heap_max_padding){
45                  padding = (magic_rand() % _magic_asr_heap_max_padding) + MINIMUM_PADDING;
46             }
47             break;
48         case MAGIC_STATE_MAP | MAGIC_ASR_FLAG_INIT:
49             if(_magic_asr_map_max_offset_pages){
50                 padding = ((magic_rand() % _magic_asr_map_max_offset_pages) + MINIMUM_PADDING) * magic_get_sys_pagesize();
51             }
52             break;
53         case MAGIC_STATE_MAP:
54             if(_magic_asr_map_max_padding_pages){
55                 padding = ((magic_rand() % _magic_asr_map_max_padding_pages) + MINIMUM_PADDING) * magic_get_sys_pagesize();
56             }
57             break;
58         default:
59             padding = -1;
60     }
61     return padding;
62 }
63 
64 PUBLIC void magic_asr_permute_dsentries(struct _magic_dsentry **first_dsentry_ptr){
65     struct _magic_dsentry *first_dsentry = *first_dsentry_ptr, *dsentry = first_dsentry, *last_dsentry;
66     int n_dsentries = 0;
67     int i;
68 
69     if(!_magic_asr_heap_map_do_permutate){
70         /*
71          * Dsentries order is reversed anyway, because newer dsentries are
72          * placed at the start of the linked list, instead of the end
73          */
74         return;
75     }
76 
77     while(dsentry != NULL){
78         last_dsentry = dsentry;
79         n_dsentries++;
80         dsentry = dsentry->next;
81     }
82 
83     for(i=0; i < n_dsentries; i++){
84         int j;
85         int pos = magic_rand() % (n_dsentries - i);
86         struct _magic_dsentry *prev_dsentry = NULL;
87 
88         if((i == 0) && (pos == (n_dsentries -1))){
89             /*
90              * Rest of for-loop won't function correctly when last dsentry is chosen first.
91              * Instead, nothing has to be done in this case.
92              */
93             continue;
94         }
95 
96         dsentry = first_dsentry;
97 
98         for(j=0;j<pos;j++){
99             prev_dsentry = dsentry;
100             dsentry = dsentry->next;
101         }
102 
103         if(pos == 0){
104             first_dsentry = first_dsentry->next;
105         }else{
106             prev_dsentry->next = dsentry->next;
107         }
108 
109         dsentry->next = NULL;
110         last_dsentry->next = dsentry;
111         last_dsentry = dsentry;
112     }
113     *first_dsentry_ptr = first_dsentry;
114 }
115 
116 PUBLIC void magic_asr_init(){
117     int seed, heap_offset;
118     if(_magic_asr_seed){
119         seed = _magic_asr_seed;
120     }else{
121         seed = magic_rand_seed();
122     }
123     magic_srand(seed);
124 
125     heap_offset = magic_asr_get_padding_size(MAGIC_STATE_HEAP|MAGIC_ASR_FLAG_INIT);
126     if(heap_offset){
127         sbrk(heap_offset);
128     }
129 }
130