Commit 08a6fac1c63233c87eec129938022f1a9a4d51f6
1 parent
5f719558ed
Exists in
master
and in
4 other branches
[PATCH] get rid of leak in compat_execve()
Even though copy_compat_strings() doesn't cache the pages, copy_strings_kernel() and stuff indirectly called by e.g. ->load_binary() is doing that, so we need to drop the cache contents in the end. [found by WANG Cong <wangcong@zeuux.org>] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 3 changed files with 11 additions and 6 deletions Side-by-side Diff
fs/compat.c
... | ... | @@ -1405,7 +1405,7 @@ |
1405 | 1405 | /* execve success */ |
1406 | 1406 | security_bprm_free(bprm); |
1407 | 1407 | acct_update_integrals(current); |
1408 | - kfree(bprm); | |
1408 | + free_bprm(bprm); | |
1409 | 1409 | return retval; |
1410 | 1410 | } |
1411 | 1411 | |
... | ... | @@ -1424,7 +1424,7 @@ |
1424 | 1424 | } |
1425 | 1425 | |
1426 | 1426 | out_kfree: |
1427 | - kfree(bprm); | |
1427 | + free_bprm(bprm); | |
1428 | 1428 | |
1429 | 1429 | out_ret: |
1430 | 1430 | return retval; |
fs/exec.c
... | ... | @@ -1251,6 +1251,12 @@ |
1251 | 1251 | |
1252 | 1252 | EXPORT_SYMBOL(search_binary_handler); |
1253 | 1253 | |
1254 | +void free_bprm(struct linux_binprm *bprm) | |
1255 | +{ | |
1256 | + free_arg_pages(bprm); | |
1257 | + kfree(bprm); | |
1258 | +} | |
1259 | + | |
1254 | 1260 | /* |
1255 | 1261 | * sys_execve() executes a new program. |
1256 | 1262 | */ |
1257 | 1263 | |
1258 | 1264 | |
... | ... | @@ -1320,17 +1326,15 @@ |
1320 | 1326 | retval = search_binary_handler(bprm,regs); |
1321 | 1327 | if (retval >= 0) { |
1322 | 1328 | /* execve success */ |
1323 | - free_arg_pages(bprm); | |
1324 | 1329 | security_bprm_free(bprm); |
1325 | 1330 | acct_update_integrals(current); |
1326 | - kfree(bprm); | |
1331 | + free_bprm(bprm); | |
1327 | 1332 | if (displaced) |
1328 | 1333 | put_files_struct(displaced); |
1329 | 1334 | return retval; |
1330 | 1335 | } |
1331 | 1336 | |
1332 | 1337 | out: |
1333 | - free_arg_pages(bprm); | |
1334 | 1338 | if (bprm->security) |
1335 | 1339 | security_bprm_free(bprm); |
1336 | 1340 | |
... | ... | @@ -1344,7 +1348,7 @@ |
1344 | 1348 | fput(bprm->file); |
1345 | 1349 | } |
1346 | 1350 | out_kfree: |
1347 | - kfree(bprm); | |
1351 | + free_bprm(bprm); | |
1348 | 1352 | |
1349 | 1353 | out_files: |
1350 | 1354 | if (displaced) |
include/linux/binfmts.h
... | ... | @@ -99,6 +99,7 @@ |
99 | 99 | extern void compute_creds(struct linux_binprm *binprm); |
100 | 100 | extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); |
101 | 101 | extern int set_binfmt(struct linux_binfmt *new); |
102 | +extern void free_bprm(struct linux_binprm *); | |
102 | 103 | |
103 | 104 | #endif /* __KERNEL__ */ |
104 | 105 | #endif /* _LINUX_BINFMTS_H */ |