67
67
#include "policycap_names.h"
68
68
#include "ima.h"
69
69
70
+ struct convert_context_args {
71
+ struct selinux_state * state ;
72
+ struct policydb * oldp ;
73
+ struct policydb * newp ;
74
+ };
75
+
76
+ struct selinux_policy_convert_data {
77
+ struct convert_context_args args ;
78
+ struct sidtab_convert_params sidtab_params ;
79
+ };
80
+
70
81
/* Forward declaration. */
71
82
static int context_struct_to_string (struct policydb * policydb ,
72
83
struct context * context ,
@@ -1974,12 +1985,6 @@ static inline int convert_context_handle_invalid_context(
1974
1985
return 0 ;
1975
1986
}
1976
1987
1977
- struct convert_context_args {
1978
- struct selinux_state * state ;
1979
- struct policydb * oldp ;
1980
- struct policydb * newp ;
1981
- };
1982
-
1983
1988
/*
1984
1989
* Convert the values in the security context
1985
1990
* structure `oldc' from the values specified
@@ -2159,15 +2164,16 @@ static void selinux_policy_cond_free(struct selinux_policy *policy)
2159
2164
}
2160
2165
2161
2166
void selinux_policy_cancel (struct selinux_state * state ,
2162
- struct selinux_policy * policy )
2167
+ struct selinux_load_state * load_state )
2163
2168
{
2164
2169
struct selinux_policy * oldpolicy ;
2165
2170
2166
2171
oldpolicy = rcu_dereference_protected (state -> policy ,
2167
2172
lockdep_is_held (& state -> policy_mutex ));
2168
2173
2169
2174
sidtab_cancel_convert (oldpolicy -> sidtab );
2170
- selinux_policy_free (policy );
2175
+ selinux_policy_free (load_state -> policy );
2176
+ kfree (load_state -> convert_data );
2171
2177
}
2172
2178
2173
2179
static void selinux_notify_policy_change (struct selinux_state * state ,
@@ -2183,9 +2189,9 @@ static void selinux_notify_policy_change(struct selinux_state *state,
2183
2189
}
2184
2190
2185
2191
void selinux_policy_commit (struct selinux_state * state ,
2186
- struct selinux_policy * newpolicy )
2192
+ struct selinux_load_state * load_state )
2187
2193
{
2188
- struct selinux_policy * oldpolicy ;
2194
+ struct selinux_policy * oldpolicy , * newpolicy = load_state -> policy ;
2189
2195
u32 seqno ;
2190
2196
2191
2197
oldpolicy = rcu_dereference_protected (state -> policy ,
@@ -2225,6 +2231,7 @@ void selinux_policy_commit(struct selinux_state *state,
2225
2231
/* Free the old policy */
2226
2232
synchronize_rcu ();
2227
2233
selinux_policy_free (oldpolicy );
2234
+ kfree (load_state -> convert_data );
2228
2235
2229
2236
/* Notify others of the policy change */
2230
2237
selinux_notify_policy_change (state , seqno );
@@ -2241,11 +2248,10 @@ void selinux_policy_commit(struct selinux_state *state,
2241
2248
* loading the new policy.
2242
2249
*/
2243
2250
int security_load_policy (struct selinux_state * state , void * data , size_t len ,
2244
- struct selinux_policy * * newpolicyp )
2251
+ struct selinux_load_state * load_state )
2245
2252
{
2246
2253
struct selinux_policy * newpolicy , * oldpolicy ;
2247
- struct sidtab_convert_params convert_params ;
2248
- struct convert_context_args args ;
2254
+ struct selinux_policy_convert_data * convert_data ;
2249
2255
int rc = 0 ;
2250
2256
struct policy_file file = { data , len }, * fp = & file ;
2251
2257
@@ -2275,10 +2281,10 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len,
2275
2281
goto err_mapping ;
2276
2282
}
2277
2283
2278
-
2279
2284
if (!selinux_initialized (state )) {
2280
2285
/* First policy load, so no need to preserve state from old policy */
2281
- * newpolicyp = newpolicy ;
2286
+ load_state -> policy = newpolicy ;
2287
+ load_state -> convert_data = NULL ;
2282
2288
return 0 ;
2283
2289
}
2284
2290
@@ -2292,29 +2298,38 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len,
2292
2298
goto err_free_isids ;
2293
2299
}
2294
2300
2301
+ convert_data = kmalloc (sizeof (* convert_data ), GFP_KERNEL );
2302
+ if (!convert_data ) {
2303
+ rc = - ENOMEM ;
2304
+ goto err_free_isids ;
2305
+ }
2306
+
2295
2307
/*
2296
2308
* Convert the internal representations of contexts
2297
2309
* in the new SID table.
2298
2310
*/
2299
- args .state = state ;
2300
- args .oldp = & oldpolicy -> policydb ;
2301
- args .newp = & newpolicy -> policydb ;
2311
+ convert_data -> args .state = state ;
2312
+ convert_data -> args .oldp = & oldpolicy -> policydb ;
2313
+ convert_data -> args .newp = & newpolicy -> policydb ;
2302
2314
2303
- convert_params .func = convert_context ;
2304
- convert_params .args = & args ;
2305
- convert_params .target = newpolicy -> sidtab ;
2315
+ convert_data -> sidtab_params .func = convert_context ;
2316
+ convert_data -> sidtab_params .args = & convert_data -> args ;
2317
+ convert_data -> sidtab_params .target = newpolicy -> sidtab ;
2306
2318
2307
- rc = sidtab_convert (oldpolicy -> sidtab , & convert_params );
2319
+ rc = sidtab_convert (oldpolicy -> sidtab , & convert_data -> sidtab_params );
2308
2320
if (rc ) {
2309
2321
pr_err ("SELinux: unable to convert the internal"
2310
2322
" representation of contexts in the new SID"
2311
2323
" table\n" );
2312
- goto err_free_isids ;
2324
+ goto err_free_convert_data ;
2313
2325
}
2314
2326
2315
- * newpolicyp = newpolicy ;
2327
+ load_state -> policy = newpolicy ;
2328
+ load_state -> convert_data = convert_data ;
2316
2329
return 0 ;
2317
2330
2331
+ err_free_convert_data :
2332
+ kfree (convert_data );
2318
2333
err_free_isids :
2319
2334
sidtab_destroy (newpolicy -> sidtab );
2320
2335
err_mapping :
0 commit comments