~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gcc-plugins/structleak_plugin.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/gcc-plugins/structleak_plugin.c (Version linux-6.12-rc7) and /scripts/gcc-plugins/structleak_plugin.c (Version linux-4.4.302)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Copyright 2013-2017 by PaX Team <pageexec@f    
  4  *                                                
  5  * Note: the choice of the license means that     
  6  *       NOT 'eligible' as defined by gcc's li    
  7  *       but for the kernel it doesn't matter     
  8  *       any of the gcc libraries                 
  9  *                                                
 10  * gcc plugin to forcibly initialize certain l    
 11  * otherwise leak kernel stack to userland if     
 12  * by later code                                  
 13  *                                                
 14  * Homepage: https://pax.grsecurity.net/          
 15  *                                                
 16  * Options:                                       
 17  * -fplugin-arg-structleak_plugin-disable         
 18  * -fplugin-arg-structleak_plugin-verbose         
 19  * -fplugin-arg-structleak_plugin-byref           
 20  * -fplugin-arg-structleak_plugin-byref-all       
 21  *                                                
 22  * Usage:                                         
 23  * $ # for 4.5/4.6/C based 4.7                    
 24  * $ gcc -I`gcc -print-file-name=plugin`/inclu    
 25  * $ # for C++ based 4.7/4.8+                     
 26  * $ g++ -I`g++ -print-file-name=plugin`/inclu    
 27  * $ gcc -fplugin=./structleak_plugin.so test.    
 28  *                                                
 29  * TODO: eliminate redundant initializers         
 30  */                                               
 31                                                   
 32 #include "gcc-common.h"                           
 33                                                   
 34 /* unused C type flag in all versions 4.5-6 */    
 35 #define TYPE_USERSPACE(TYPE) TYPE_LANG_FLAG_5(    
 36                                                   
 37 __visible int plugin_is_GPL_compatible;           
 38                                                   
 39 static struct plugin_info structleak_plugin_in    
 40         .version        = PLUGIN_VERSION,         
 41         .help           = "disable\tdo not act    
 42                           "byref\tinit structs    
 43                           "byref-all\tinit any    
 44                           "verbose\tprint all     
 45 };                                                
 46                                                   
 47 #define BYREF_STRUCT    1                         
 48 #define BYREF_ALL       2                         
 49                                                   
 50 static bool verbose;                              
 51 static int byref;                                 
 52                                                   
 53 static tree handle_user_attribute(tree *node,     
 54 {                                                 
 55         *no_add_attrs = true;                     
 56                                                   
 57         /* check for types? for now accept eve    
 58         if (TREE_CODE(*node) != FIELD_DECL)       
 59                 return NULL_TREE;                 
 60                                                   
 61         *no_add_attrs = false;                    
 62         return NULL_TREE;                         
 63 }                                                 
 64                                                   
 65 static struct attribute_spec user_attr = { };     
 66                                                   
 67 static void register_attributes(void *event_da    
 68 {                                                 
 69         user_attr.name                  = "use    
 70         user_attr.handler               = hand    
 71         user_attr.affects_type_identity = true    
 72                                                   
 73         register_attribute(&user_attr);           
 74 }                                                 
 75                                                   
 76 static tree get_field_type(tree field)            
 77 {                                                 
 78         return strip_array_types(TREE_TYPE(fie    
 79 }                                                 
 80                                                   
 81 static bool is_userspace_type(tree type)          
 82 {                                                 
 83         tree field;                               
 84                                                   
 85         for (field = TYPE_FIELDS(type); field;    
 86                 tree fieldtype = get_field_typ    
 87                 enum tree_code code = TREE_COD    
 88                                                   
 89                 if (code == RECORD_TYPE || cod    
 90                         if (is_userspace_type(    
 91                                 return true;      
 92                                                   
 93                 if (lookup_attribute("user", D    
 94                         return true;              
 95         }                                         
 96         return false;                             
 97 }                                                 
 98                                                   
 99 static void finish_type(void *event_data, void    
100 {                                                 
101         tree type = (tree)event_data;             
102                                                   
103         if (type == NULL_TREE || type == error    
104                 return;                           
105                                                   
106         if (TREE_CODE(type) == ENUMERAL_TYPE)     
107                 return;                           
108                                                   
109         if (TYPE_USERSPACE(type))                 
110                 return;                           
111                                                   
112         if (is_userspace_type(type))              
113                 TYPE_USERSPACE(type) = 1;         
114 }                                                 
115                                                   
116 static void initialize(tree var)                  
117 {                                                 
118         basic_block bb;                           
119         gimple_stmt_iterator gsi;                 
120         tree initializer;                         
121         gimple init_stmt;                         
122         tree type;                                
123                                                   
124         /* this is the original entry bb befor    
125         bb = single_succ(ENTRY_BLOCK_PTR_FOR_F    
126                                                   
127         /* first check if variable is already     
128         for (gsi = gsi_start_bb(bb); !gsi_end_    
129                 gimple stmt = gsi_stmt(gsi);      
130                 tree rhs1;                        
131                                                   
132                 /* we're looking for an assign    
133                 if (!gimple_assign_single_p(st    
134                         continue;                 
135                 rhs1 = gimple_assign_rhs1(stmt    
136                 /* ... of a non-clobbering exp    
137                 if (TREE_CLOBBER_P(rhs1))         
138                         continue;                 
139                 /* ... to our variable... */      
140                 if (gimple_get_lhs(stmt) != va    
141                         continue;                 
142                 /* if it's an initializer then    
143                 if (TREE_CODE(rhs1) == CONSTRU    
144                         return;                   
145         }                                         
146                                                   
147         /* these aren't the 0days you're looki    
148         if (verbose)                              
149                 inform(DECL_SOURCE_LOCATION(va    
150                         "%s variable will be f    
151                         (byref && TREE_ADDRESS    
152                                                   
153                                                   
154         /* build the initializer expression */    
155         type = TREE_TYPE(var);                    
156         if (AGGREGATE_TYPE_P(type))               
157                 initializer = build_constructo    
158         else                                      
159                 initializer = fold_convert(typ    
160                                                   
161         /* build the initializer stmt */          
162         init_stmt = gimple_build_assign(var, i    
163         gsi = gsi_after_labels(single_succ(ENT    
164         gsi_insert_before(&gsi, init_stmt, GSI    
165         update_stmt(init_stmt);                   
166 }                                                 
167                                                   
168 static unsigned int structleak_execute(void)      
169 {                                                 
170         basic_block bb;                           
171         tree var;                                 
172         unsigned int i;                           
173                                                   
174         /* split the first bb where we can put    
175         gcc_assert(single_succ_p(ENTRY_BLOCK_P    
176         bb = single_succ(ENTRY_BLOCK_PTR_FOR_F    
177         if (!single_pred_p(bb)) {                 
178                 split_edge(single_succ_edge(EN    
179                 gcc_assert(single_succ_p(ENTRY    
180         }                                         
181                                                   
182         /* enumerate all local variables and f    
183         FOR_EACH_LOCAL_DECL(cfun, i, var) {       
184                 tree type = TREE_TYPE(var);       
185                                                   
186                 gcc_assert(DECL_P(var));          
187                 if (!auto_var_in_fn_p(var, cur    
188                         continue;                 
189                                                   
190                 /* only care about structure t    
191                 if (byref != BYREF_ALL && TREE    
192                         continue;                 
193                                                   
194                 /* if the type is of interest,    
195                 if (TYPE_USERSPACE(type) ||       
196                     (byref && TREE_ADDRESSABLE    
197                         initialize(var);          
198         }                                         
199                                                   
200         return 0;                                 
201 }                                                 
202                                                   
203 #define PASS_NAME structleak                      
204 #define NO_GATE                                   
205 #define PROPERTIES_REQUIRED PROP_cfg              
206 #define TODO_FLAGS_FINISH TODO_verify_il | TOD    
207 #include "gcc-generate-gimple-pass.h"             
208                                                   
209 __visible int plugin_init(struct plugin_name_a    
210 {                                                 
211         int i;                                    
212         const char * const plugin_name = plugi    
213         const int argc = plugin_info->argc;       
214         const struct plugin_argument * const a    
215         bool enable = true;                       
216                                                   
217         PASS_INFO(structleak, "early_optimizat    
218                                                   
219         if (!plugin_default_version_check(vers    
220                 error(G_("incompatible gcc/plu    
221                 return 1;                         
222         }                                         
223                                                   
224         if (strncmp(lang_hooks.name, "GNU C",     
225                 inform(UNKNOWN_LOCATION, G_("%    
226                 enable = false;                   
227         }                                         
228                                                   
229         for (i = 0; i < argc; ++i) {              
230                 if (!strcmp(argv[i].key, "disa    
231                         enable = false;           
232                         continue;                 
233                 }                                 
234                 if (!strcmp(argv[i].key, "verb    
235                         verbose = true;           
236                         continue;                 
237                 }                                 
238                 if (!strcmp(argv[i].key, "byre    
239                         byref = BYREF_STRUCT;     
240                         continue;                 
241                 }                                 
242                 if (!strcmp(argv[i].key, "byre    
243                         byref = BYREF_ALL;        
244                         continue;                 
245                 }                                 
246                 error(G_("unknown option '-fpl    
247         }                                         
248                                                   
249         register_callback(plugin_name, PLUGIN_    
250         if (enable) {                             
251                 register_callback(plugin_name,    
252                 register_callback(plugin_name,    
253         }                                         
254         register_callback(plugin_name, PLUGIN_    
255                                                   
256         return 0;                                 
257 }                                                 
258                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php