diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 11:28:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 11:28:34 -0400 |
| commit | 4d9dec4db2efbd7edb549bd02373995b67496983 (patch) | |
| tree | a0ddbecea4823a7f3e20ab6eacb37a086a72dc36 | |
| parent | 34b064569eba3bec65bf98efe057b0578fe13297 (diff) | |
| parent | ae6b585eeb74670a2dec1fe4394bdfbdb9395cc2 (diff) | |
Merge branch 'exec_rm_compat' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc
* 'exec_rm_compat' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc:
exec: document acct_arg_size()
exec: unify do_execve/compat_do_execve code
exec: introduce struct user_arg_ptr
exec: introduce get_user_arg_ptr() helper
| -rw-r--r-- | fs/compat.c | 235 | ||||
| -rw-r--r-- | fs/exec.c | 125 | ||||
| -rw-r--r-- | include/linux/binfmts.h | 4 |
3 files changed, 100 insertions, 264 deletions
diff --git a/fs/compat.c b/fs/compat.c index 72fe6cda9108..0ea00832de23 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1306,241 +1306,6 @@ compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int | |||
| 1306 | return do_sys_open(dfd, filename, flags, mode); | 1306 | return do_sys_open(dfd, filename, flags, mode); |
| 1307 | } | 1307 | } |
| 1308 | 1308 | ||
| 1309 | /* | ||
| 1310 | * compat_count() counts the number of arguments/envelopes. It is basically | ||
| 1311 | * a copy of count() from fs/exec.c, except that it works with 32 bit argv | ||
| 1312 | * and envp pointers. | ||
| 1313 | */ | ||
| 1314 | static int compat_count(compat_uptr_t __user *argv, int max) | ||
| 1315 | { | ||
| 1316 | int i = 0; | ||
| 1317 | |||
| 1318 | if (argv != NULL) { | ||
| 1319 | for (;;) { | ||
| 1320 | compat_uptr_t p; | ||
| 1321 | |||
| 1322 | if (get_user(p, argv)) | ||
| 1323 | return -EFAULT; | ||
| 1324 | if (!p) | ||
| 1325 | break; | ||
| 1326 | argv++; | ||
| 1327 | if (i++ >= max) | ||
| 1328 | return -E2BIG; | ||
| 1329 | |||
| 1330 | if (fatal_signal_pending(current)) | ||
| 1331 | return -ERESTARTNOHAND; | ||
| 1332 | cond_resched(); | ||
| 1333 | } | ||
| 1334 | } | ||
| 1335 | return i; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | /* | ||
| 1339 | * compat_copy_strings() is basically a copy of copy_strings() from fs/exec.c | ||
| 1340 | * except that it works with 32 bit argv and envp pointers. | ||
| 1341 | */ | ||
| 1342 | static int compat_copy_strings(int argc, compat_uptr_t __user *argv, | ||
| 1343 | struct linux_binprm *bprm) | ||
| 1344 | { | ||
| 1345 | struct page *kmapped_page = NULL; | ||
| 1346 | char *kaddr = NULL; | ||
| 1347 | unsigned long kpos = 0; | ||
| 1348 | int ret; | ||
| 1349 | |||
| 1350 | while (argc-- > 0) { | ||
| 1351 | compat_uptr_t str; | ||
| 1352 | int len; | ||
| 1353 | unsigned long pos; | ||
| 1354 | |||
| 1355 | if (get_user(str, argv+argc) || | ||
| 1356 | !(len = strnlen_user(compat_ptr(str), MAX_ARG_STRLEN))) { | ||
| 1357 | ret = -EFAULT; | ||
| 1358 | goto out; | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | if (len > MAX_ARG_STRLEN) { | ||
| 1362 | ret = -E2BIG; | ||
| 1363 | goto out; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | /* We're going to work our way backwords. */ | ||
| 1367 | pos = bprm->p; | ||
| 1368 | str += len; | ||
| 1369 | bprm->p -= len; | ||
| 1370 | |||
| 1371 | while (len > 0) { | ||
| 1372 | int offset, bytes_to_copy; | ||
| 1373 | |||
| 1374 | if (fatal_signal_pending(current)) { | ||
| 1375 | ret = -ERESTARTNOHAND; | ||
| 1376 | goto out; | ||
| 1377 | } | ||
| 1378 | cond_resched(); | ||
| 1379 | |||
| 1380 | offset = pos % PAGE_SIZE; | ||
| 1381 | if (offset == 0) | ||
| 1382 | offset = PAGE_SIZE; | ||
| 1383 | |||
| 1384 | bytes_to_copy = offset; | ||
| 1385 | if (bytes_to_copy > len) | ||
| 1386 | bytes_to_copy = len; | ||
| 1387 | |||
| 1388 | offset -= bytes_to_copy; | ||
| 1389 | pos -= bytes_to_copy; | ||
| 1390 | str -= bytes_to_copy; | ||
| 1391 | len -= bytes_to_copy; | ||
| 1392 | |||
| 1393 | if (!kmapped_page || kpos != (pos & PAGE_MASK)) { | ||
| 1394 | struct page *page; | ||
| 1395 | |||
| 1396 | page = get_arg_page(bprm, pos, 1); | ||
| 1397 | if (!page) { | ||
| 1398 | ret = -E2BIG; | ||
| 1399 | goto out; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | if (kmapped_page) { | ||
| 1403 | flush_kernel_dcache_page(kmapped_page); | ||
| 1404 | kunmap(kmapped_page); | ||
| 1405 | put_page(kmapped_page); | ||
| 1406 | } | ||
| 1407 | kmapped_page = page; | ||
| 1408 | kaddr = kmap(kmapped_page); | ||
| 1409 | kpos = pos & PAGE_MASK; | ||
| 1410 | flush_cache_page(bprm->vma, kpos, | ||
| 1411 | page_to_pfn(kmapped_page)); | ||
| 1412 | } | ||
| 1413 | if (copy_from_user(kaddr+offset, compat_ptr(str), | ||
| 1414 | bytes_to_copy)) { | ||
| 1415 | ret = -EFAULT; | ||
| 1416 | goto out; | ||
| 1417 | } | ||
| 1418 | } | ||
| 1419 | } | ||
| 1420 | ret = 0; | ||
| 1421 | out: | ||
| 1422 | if (kmapped_page) { | ||
| 1423 | flush_kernel_dcache_page(kmapped_page); | ||
| 1424 | kunmap(kmapped_page); | ||
| 1425 | put_page(kmapped_page); | ||
| 1426 | } | ||
| 1427 | return ret; | ||
| 1428 | } | ||
| 1429 | |||
| 1430 | /* | ||
| 1431 | * compat_do_execve() is mostly a copy of do_execve(), with the exception | ||
| 1432 | * that it processes 32 bit argv and envp pointers. | ||
| 1433 | */ | ||
| 1434 | int compat_do_execve(char * filename, | ||
| 1435 | compat_uptr_t __user *argv, | ||
| 1436 | compat_uptr_t __user *envp, | ||
| 1437 | struct pt_regs * regs) | ||
| 1438 | { | ||
| 1439 | struct linux_binprm *bprm; | ||
| 1440 | struct file *file; | ||
| 1441 | struct files_struct *displaced; | ||
| 1442 | bool clear_in_exec; | ||
| 1443 | int retval; | ||
| 1444 | |||
| 1445 | retval = unshare_files(&displaced); | ||
| 1446 | if (retval) | ||
| 1447 | goto out_ret; | ||
| 1448 | |||
| 1449 | retval = -ENOMEM; | ||
| 1450 | bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); | ||
| 1451 | if (!bprm) | ||
| 1452 | goto out_files; | ||
| 1453 | |||
| 1454 | retval = prepare_bprm_creds(bprm); | ||
| 1455 | if (retval) | ||
| 1456 | goto out_free; | ||
| 1457 | |||
| 1458 | retval = check_unsafe_exec(bprm); | ||
| 1459 | if (retval < 0) | ||
| 1460 | goto out_free; | ||
| 1461 | clear_in_exec = retval; | ||
| 1462 | current->in_execve = 1; | ||
| 1463 | |||
| 1464 | file = open_exec(filename); | ||
| 1465 | retval = PTR_ERR(file); | ||
| 1466 | if (IS_ERR(file)) | ||
| 1467 | goto out_unmark; | ||
| 1468 | |||
| 1469 | sched_exec(); | ||
| 1470 | |||
| 1471 | bprm->file = file; | ||
| 1472 | bprm->filename = filename; | ||
| 1473 | bprm->interp = filename; | ||
| 1474 | |||
| 1475 | retval = bprm_mm_init(bprm); | ||
| 1476 | if (retval) | ||
| 1477 | goto out_file; | ||
| 1478 | |||
| 1479 | bprm->argc = compat_count(argv, MAX_ARG_STRINGS); | ||
| 1480 | if ((retval = bprm->argc) < 0) | ||
| 1481 | goto out; | ||
| 1482 | |||
| 1483 | bprm->envc = compat_count(envp, MAX_ARG_STRINGS); | ||
| 1484 | if ((retval = bprm->envc) < 0) | ||
| 1485 | goto out; | ||
| 1486 | |||
| 1487 | retval = prepare_binprm(bprm); | ||
| 1488 | if (retval < 0) | ||
| 1489 | goto out; | ||
| 1490 | |||
| 1491 | retval = copy_strings_kernel(1, &bprm->filename, bprm); | ||
| 1492 | if (retval < 0) | ||
| 1493 | goto out; | ||
| 1494 | |||
| 1495 | bprm->exec = bprm->p; | ||
| 1496 | retval = compat_copy_strings(bprm->envc, envp, bprm); | ||
| 1497 | if (retval < 0) | ||
| 1498 | goto out; | ||
| 1499 | |||
| 1500 | retval = compat_copy_strings(bprm->argc, argv, bprm); | ||
| 1501 | if (retval < 0) | ||
| 1502 | goto out; | ||
| 1503 | |||
| 1504 | retval = search_binary_handler(bprm, regs); | ||
| 1505 | if (retval < 0) | ||
| 1506 | goto out; | ||
| 1507 | |||
| 1508 | /* execve succeeded */ | ||
| 1509 | current->fs->in_exec = 0; | ||
| 1510 | current->in_execve = 0; | ||
| 1511 | acct_update_integrals(current); | ||
| 1512 | free_bprm(bprm); | ||
| 1513 | if (displaced) | ||
| 1514 | put_files_struct(displaced); | ||
| 1515 | return retval; | ||
| 1516 | |||
| 1517 | out: | ||
| 1518 | if (bprm->mm) { | ||
| 1519 | acct_arg_size(bprm, 0); | ||
| 1520 | mmput(bprm->mm); | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | out_file: | ||
| 1524 | if (bprm->file) { | ||
| 1525 | allow_write_access(bprm->file); | ||
| 1526 | fput(bprm->file); | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | out_unmark: | ||
| 1530 | if (clear_in_exec) | ||
| 1531 | current->fs->in_exec = 0; | ||
| 1532 | current->in_execve = 0; | ||
| 1533 | |||
| 1534 | out_free: | ||
| 1535 | free_bprm(bprm); | ||
| 1536 | |||
| 1537 | out_files: | ||
| 1538 | if (displaced) | ||
| 1539 | reset_files_struct(displaced); | ||
| 1540 | out_ret: | ||
| 1541 | return retval; | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) | 1309 | #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) |
| 1545 | 1310 | ||
| 1546 | static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, | 1311 | static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, |
| @@ -55,6 +55,7 @@ | |||
| 55 | #include <linux/fs_struct.h> | 55 | #include <linux/fs_struct.h> |
| 56 | #include <linux/pipe_fs_i.h> | 56 | #include <linux/pipe_fs_i.h> |
| 57 | #include <linux/oom.h> | 57 | #include <linux/oom.h> |
| 58 | #include <linux/compat.h> | ||
| 58 | 59 | ||
| 59 | #include <asm/uaccess.h> | 60 | #include <asm/uaccess.h> |
| 60 | #include <asm/mmu_context.h> | 61 | #include <asm/mmu_context.h> |
| @@ -166,8 +167,13 @@ out: | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | #ifdef CONFIG_MMU | 169 | #ifdef CONFIG_MMU |
| 169 | 170 | /* | |
| 170 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | 171 | * The nascent bprm->mm is not visible until exec_mmap() but it can |
| 172 | * use a lot of memory, account these pages in current->mm temporary | ||
| 173 | * for oom_badness()->get_mm_rss(). Once exec succeeds or fails, we | ||
| 174 | * change the counter back via acct_arg_size(0). | ||
| 175 | */ | ||
| 176 | static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | ||
| 171 | { | 177 | { |
| 172 | struct mm_struct *mm = current->mm; | 178 | struct mm_struct *mm = current->mm; |
| 173 | long diff = (long)(pages - bprm->vma_pages); | 179 | long diff = (long)(pages - bprm->vma_pages); |
| @@ -186,7 +192,7 @@ void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | |||
| 186 | #endif | 192 | #endif |
| 187 | } | 193 | } |
| 188 | 194 | ||
| 189 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 195 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
| 190 | int write) | 196 | int write) |
| 191 | { | 197 | { |
| 192 | struct page *page; | 198 | struct page *page; |
| @@ -305,11 +311,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) | |||
| 305 | 311 | ||
| 306 | #else | 312 | #else |
| 307 | 313 | ||
| 308 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | 314 | static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
| 309 | { | 315 | { |
| 310 | } | 316 | } |
| 311 | 317 | ||
| 312 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 318 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
| 313 | int write) | 319 | int write) |
| 314 | { | 320 | { |
| 315 | struct page *page; | 321 | struct page *page; |
| @@ -398,22 +404,56 @@ err: | |||
| 398 | return err; | 404 | return err; |
| 399 | } | 405 | } |
| 400 | 406 | ||
| 407 | struct user_arg_ptr { | ||
| 408 | #ifdef CONFIG_COMPAT | ||
| 409 | bool is_compat; | ||
| 410 | #endif | ||
| 411 | union { | ||
| 412 | const char __user *const __user *native; | ||
| 413 | #ifdef CONFIG_COMPAT | ||
| 414 | compat_uptr_t __user *compat; | ||
| 415 | #endif | ||
| 416 | } ptr; | ||
| 417 | }; | ||
| 418 | |||
| 419 | static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) | ||
| 420 | { | ||
| 421 | const char __user *native; | ||
| 422 | |||
| 423 | #ifdef CONFIG_COMPAT | ||
| 424 | if (unlikely(argv.is_compat)) { | ||
| 425 | compat_uptr_t compat; | ||
| 426 | |||
| 427 | if (get_user(compat, argv.ptr.compat + nr)) | ||
| 428 | return ERR_PTR(-EFAULT); | ||
| 429 | |||
| 430 | return compat_ptr(compat); | ||
| 431 | } | ||
| 432 | #endif | ||
| 433 | |||
| 434 | if (get_user(native, argv.ptr.native + nr)) | ||
| 435 | return ERR_PTR(-EFAULT); | ||
| 436 | |||
| 437 | return native; | ||
| 438 | } | ||
| 439 | |||
| 401 | /* | 440 | /* |
| 402 | * count() counts the number of strings in array ARGV. | 441 | * count() counts the number of strings in array ARGV. |
| 403 | */ | 442 | */ |
| 404 | static int count(const char __user * const __user * argv, int max) | 443 | static int count(struct user_arg_ptr argv, int max) |
| 405 | { | 444 | { |
| 406 | int i = 0; | 445 | int i = 0; |
| 407 | 446 | ||
| 408 | if (argv != NULL) { | 447 | if (argv.ptr.native != NULL) { |
| 409 | for (;;) { | 448 | for (;;) { |
| 410 | const char __user * p; | 449 | const char __user *p = get_user_arg_ptr(argv, i); |
| 411 | 450 | ||
| 412 | if (get_user(p, argv)) | ||
| 413 | return -EFAULT; | ||
| 414 | if (!p) | 451 | if (!p) |
| 415 | break; | 452 | break; |
| 416 | argv++; | 453 | |
| 454 | if (IS_ERR(p)) | ||
| 455 | return -EFAULT; | ||
| 456 | |||
| 417 | if (i++ >= max) | 457 | if (i++ >= max) |
| 418 | return -E2BIG; | 458 | return -E2BIG; |
| 419 | 459 | ||
| @@ -430,7 +470,7 @@ static int count(const char __user * const __user * argv, int max) | |||
| 430 | * processes's memory to the new process's stack. The call to get_user_pages() | 470 | * processes's memory to the new process's stack. The call to get_user_pages() |
| 431 | * ensures the destination page is created and not swapped out. | 471 | * ensures the destination page is created and not swapped out. |
| 432 | */ | 472 | */ |
| 433 | static int copy_strings(int argc, const char __user *const __user *argv, | 473 | static int copy_strings(int argc, struct user_arg_ptr argv, |
| 434 | struct linux_binprm *bprm) | 474 | struct linux_binprm *bprm) |
| 435 | { | 475 | { |
| 436 | struct page *kmapped_page = NULL; | 476 | struct page *kmapped_page = NULL; |
| @@ -443,16 +483,18 @@ static int copy_strings(int argc, const char __user *const __user *argv, | |||
| 443 | int len; | 483 | int len; |
| 444 | unsigned long pos; | 484 | unsigned long pos; |
| 445 | 485 | ||
| 446 | if (get_user(str, argv+argc) || | 486 | ret = -EFAULT; |
| 447 | !(len = strnlen_user(str, MAX_ARG_STRLEN))) { | 487 | str = get_user_arg_ptr(argv, argc); |
| 448 | ret = -EFAULT; | 488 | if (IS_ERR(str)) |
| 449 | goto out; | 489 | goto out; |
| 450 | } | ||
| 451 | 490 | ||
| 452 | if (!valid_arg_len(bprm, len)) { | 491 | len = strnlen_user(str, MAX_ARG_STRLEN); |
| 453 | ret = -E2BIG; | 492 | if (!len) |
| 493 | goto out; | ||
| 494 | |||
| 495 | ret = -E2BIG; | ||
| 496 | if (!valid_arg_len(bprm, len)) | ||
| 454 | goto out; | 497 | goto out; |
| 455 | } | ||
| 456 | 498 | ||
| 457 | /* We're going to work our way backwords. */ | 499 | /* We're going to work our way backwords. */ |
| 458 | pos = bprm->p; | 500 | pos = bprm->p; |
| @@ -519,14 +561,19 @@ out: | |||
| 519 | /* | 561 | /* |
| 520 | * Like copy_strings, but get argv and its values from kernel memory. | 562 | * Like copy_strings, but get argv and its values from kernel memory. |
| 521 | */ | 563 | */ |
| 522 | int copy_strings_kernel(int argc, const char *const *argv, | 564 | int copy_strings_kernel(int argc, const char *const *__argv, |
| 523 | struct linux_binprm *bprm) | 565 | struct linux_binprm *bprm) |
| 524 | { | 566 | { |
| 525 | int r; | 567 | int r; |
| 526 | mm_segment_t oldfs = get_fs(); | 568 | mm_segment_t oldfs = get_fs(); |
| 569 | struct user_arg_ptr argv = { | ||
| 570 | .ptr.native = (const char __user *const __user *)__argv, | ||
| 571 | }; | ||
| 572 | |||
| 527 | set_fs(KERNEL_DS); | 573 | set_fs(KERNEL_DS); |
| 528 | r = copy_strings(argc, (const char __user *const __user *)argv, bprm); | 574 | r = copy_strings(argc, argv, bprm); |
| 529 | set_fs(oldfs); | 575 | set_fs(oldfs); |
| 576 | |||
| 530 | return r; | 577 | return r; |
| 531 | } | 578 | } |
| 532 | EXPORT_SYMBOL(copy_strings_kernel); | 579 | EXPORT_SYMBOL(copy_strings_kernel); |
| @@ -1379,10 +1426,10 @@ EXPORT_SYMBOL(search_binary_handler); | |||
| 1379 | /* | 1426 | /* |
| 1380 | * sys_execve() executes a new program. | 1427 | * sys_execve() executes a new program. |
| 1381 | */ | 1428 | */ |
| 1382 | int do_execve(const char * filename, | 1429 | static int do_execve_common(const char *filename, |
| 1383 | const char __user *const __user *argv, | 1430 | struct user_arg_ptr argv, |
| 1384 | const char __user *const __user *envp, | 1431 | struct user_arg_ptr envp, |
| 1385 | struct pt_regs * regs) | 1432 | struct pt_regs *regs) |
| 1386 | { | 1433 | { |
| 1387 | struct linux_binprm *bprm; | 1434 | struct linux_binprm *bprm; |
| 1388 | struct file *file; | 1435 | struct file *file; |
| @@ -1489,6 +1536,34 @@ out_ret: | |||
| 1489 | return retval; | 1536 | return retval; |
| 1490 | } | 1537 | } |
| 1491 | 1538 | ||
| 1539 | int do_execve(const char *filename, | ||
| 1540 | const char __user *const __user *__argv, | ||
| 1541 | const char __user *const __user *__envp, | ||
| 1542 | struct pt_regs *regs) | ||
| 1543 | { | ||
| 1544 | struct user_arg_ptr argv = { .ptr.native = __argv }; | ||
| 1545 | struct user_arg_ptr envp = { .ptr.native = __envp }; | ||
| 1546 | return do_execve_common(filename, argv, envp, regs); | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | #ifdef CONFIG_COMPAT | ||
| 1550 | int compat_do_execve(char *filename, | ||
| 1551 | compat_uptr_t __user *__argv, | ||
| 1552 | compat_uptr_t __user *__envp, | ||
| 1553 | struct pt_regs *regs) | ||
| 1554 | { | ||
| 1555 | struct user_arg_ptr argv = { | ||
| 1556 | .is_compat = true, | ||
| 1557 | .ptr.compat = __argv, | ||
| 1558 | }; | ||
| 1559 | struct user_arg_ptr envp = { | ||
| 1560 | .is_compat = true, | ||
| 1561 | .ptr.compat = __envp, | ||
| 1562 | }; | ||
| 1563 | return do_execve_common(filename, argv, envp, regs); | ||
| 1564 | } | ||
| 1565 | #endif | ||
| 1566 | |||
| 1492 | void set_binfmt(struct linux_binfmt *new) | 1567 | void set_binfmt(struct linux_binfmt *new) |
| 1493 | { | 1568 | { |
| 1494 | struct mm_struct *mm = current->mm; | 1569 | struct mm_struct *mm = current->mm; |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c3d6512eded1..8845613fd7e3 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
| @@ -60,10 +60,6 @@ struct linux_binprm { | |||
| 60 | unsigned long loader, exec; | 60 | unsigned long loader, exec; |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages); | ||
| 64 | extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | ||
| 65 | int write); | ||
| 66 | |||
| 67 | #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 | 63 | #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 |
| 68 | #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) | 64 | #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) |
| 69 | 65 | ||
