diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 173 |
1 files changed, 106 insertions, 67 deletions
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/fsnotify.h> | 54 | #include <linux/fsnotify.h> |
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 | 58 | ||
58 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
59 | #include <asm/mmu_context.h> | 60 | #include <asm/mmu_context.h> |
@@ -65,6 +66,12 @@ char core_pattern[CORENAME_MAX_SIZE] = "core"; | |||
65 | unsigned int core_pipe_limit; | 66 | unsigned int core_pipe_limit; |
66 | int suid_dumpable = 0; | 67 | int suid_dumpable = 0; |
67 | 68 | ||
69 | struct core_name { | ||
70 | char *corename; | ||
71 | int used, size; | ||
72 | }; | ||
73 | static atomic_t call_count = ATOMIC_INIT(1); | ||
74 | |||
68 | /* The maximal length of core_pattern is also specified in sysctl.c */ | 75 | /* The maximal length of core_pattern is also specified in sysctl.c */ |
69 | 76 | ||
70 | static LIST_HEAD(formats); | 77 | static LIST_HEAD(formats); |
@@ -759,6 +766,10 @@ static int exec_mmap(struct mm_struct *mm) | |||
759 | tsk->mm = mm; | 766 | tsk->mm = mm; |
760 | tsk->active_mm = mm; | 767 | tsk->active_mm = mm; |
761 | activate_mm(active_mm, mm); | 768 | activate_mm(active_mm, mm); |
769 | if (old_mm && tsk->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) { | ||
770 | atomic_dec(&old_mm->oom_disable_count); | ||
771 | atomic_inc(&tsk->mm->oom_disable_count); | ||
772 | } | ||
762 | task_unlock(tsk); | 773 | task_unlock(tsk); |
763 | arch_pick_mmap_layout(mm); | 774 | arch_pick_mmap_layout(mm); |
764 | if (old_mm) { | 775 | if (old_mm) { |
@@ -998,7 +1009,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
998 | 1009 | ||
999 | bprm->mm = NULL; /* We're using it now */ | 1010 | bprm->mm = NULL; /* We're using it now */ |
1000 | 1011 | ||
1001 | current->flags &= ~PF_RANDOMIZE; | 1012 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); |
1002 | flush_thread(); | 1013 | flush_thread(); |
1003 | current->personality &= ~bprm->per_clear; | 1014 | current->personality &= ~bprm->per_clear; |
1004 | 1015 | ||
@@ -1078,14 +1089,14 @@ EXPORT_SYMBOL(setup_new_exec); | |||
1078 | */ | 1089 | */ |
1079 | int prepare_bprm_creds(struct linux_binprm *bprm) | 1090 | int prepare_bprm_creds(struct linux_binprm *bprm) |
1080 | { | 1091 | { |
1081 | if (mutex_lock_interruptible(¤t->cred_guard_mutex)) | 1092 | if (mutex_lock_interruptible(¤t->signal->cred_guard_mutex)) |
1082 | return -ERESTARTNOINTR; | 1093 | return -ERESTARTNOINTR; |
1083 | 1094 | ||
1084 | bprm->cred = prepare_exec_creds(); | 1095 | bprm->cred = prepare_exec_creds(); |
1085 | if (likely(bprm->cred)) | 1096 | if (likely(bprm->cred)) |
1086 | return 0; | 1097 | return 0; |
1087 | 1098 | ||
1088 | mutex_unlock(¤t->cred_guard_mutex); | 1099 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1089 | return -ENOMEM; | 1100 | return -ENOMEM; |
1090 | } | 1101 | } |
1091 | 1102 | ||
@@ -1093,7 +1104,7 @@ void free_bprm(struct linux_binprm *bprm) | |||
1093 | { | 1104 | { |
1094 | free_arg_pages(bprm); | 1105 | free_arg_pages(bprm); |
1095 | if (bprm->cred) { | 1106 | if (bprm->cred) { |
1096 | mutex_unlock(¤t->cred_guard_mutex); | 1107 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1097 | abort_creds(bprm->cred); | 1108 | abort_creds(bprm->cred); |
1098 | } | 1109 | } |
1099 | kfree(bprm); | 1110 | kfree(bprm); |
@@ -1114,13 +1125,13 @@ void install_exec_creds(struct linux_binprm *bprm) | |||
1114 | * credentials; any time after this it may be unlocked. | 1125 | * credentials; any time after this it may be unlocked. |
1115 | */ | 1126 | */ |
1116 | security_bprm_committed_creds(bprm); | 1127 | security_bprm_committed_creds(bprm); |
1117 | mutex_unlock(¤t->cred_guard_mutex); | 1128 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1118 | } | 1129 | } |
1119 | EXPORT_SYMBOL(install_exec_creds); | 1130 | EXPORT_SYMBOL(install_exec_creds); |
1120 | 1131 | ||
1121 | /* | 1132 | /* |
1122 | * determine how safe it is to execute the proposed program | 1133 | * determine how safe it is to execute the proposed program |
1123 | * - the caller must hold current->cred_guard_mutex to protect against | 1134 | * - the caller must hold ->cred_guard_mutex to protect against |
1124 | * PTRACE_ATTACH | 1135 | * PTRACE_ATTACH |
1125 | */ | 1136 | */ |
1126 | int check_unsafe_exec(struct linux_binprm *bprm) | 1137 | int check_unsafe_exec(struct linux_binprm *bprm) |
@@ -1401,7 +1412,6 @@ int do_execve(const char * filename, | |||
1401 | if (retval < 0) | 1412 | if (retval < 0) |
1402 | goto out; | 1413 | goto out; |
1403 | 1414 | ||
1404 | current->flags &= ~PF_KTHREAD; | ||
1405 | retval = search_binary_handler(bprm,regs); | 1415 | retval = search_binary_handler(bprm,regs); |
1406 | if (retval < 0) | 1416 | if (retval < 0) |
1407 | goto out; | 1417 | goto out; |
@@ -1454,127 +1464,148 @@ void set_binfmt(struct linux_binfmt *new) | |||
1454 | 1464 | ||
1455 | EXPORT_SYMBOL(set_binfmt); | 1465 | EXPORT_SYMBOL(set_binfmt); |
1456 | 1466 | ||
1467 | static int expand_corename(struct core_name *cn) | ||
1468 | { | ||
1469 | char *old_corename = cn->corename; | ||
1470 | |||
1471 | cn->size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count); | ||
1472 | cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL); | ||
1473 | |||
1474 | if (!cn->corename) { | ||
1475 | kfree(old_corename); | ||
1476 | return -ENOMEM; | ||
1477 | } | ||
1478 | |||
1479 | return 0; | ||
1480 | } | ||
1481 | |||
1482 | static int cn_printf(struct core_name *cn, const char *fmt, ...) | ||
1483 | { | ||
1484 | char *cur; | ||
1485 | int need; | ||
1486 | int ret; | ||
1487 | va_list arg; | ||
1488 | |||
1489 | va_start(arg, fmt); | ||
1490 | need = vsnprintf(NULL, 0, fmt, arg); | ||
1491 | va_end(arg); | ||
1492 | |||
1493 | if (likely(need < cn->size - cn->used - 1)) | ||
1494 | goto out_printf; | ||
1495 | |||
1496 | ret = expand_corename(cn); | ||
1497 | if (ret) | ||
1498 | goto expand_fail; | ||
1499 | |||
1500 | out_printf: | ||
1501 | cur = cn->corename + cn->used; | ||
1502 | va_start(arg, fmt); | ||
1503 | vsnprintf(cur, need + 1, fmt, arg); | ||
1504 | va_end(arg); | ||
1505 | cn->used += need; | ||
1506 | return 0; | ||
1507 | |||
1508 | expand_fail: | ||
1509 | return ret; | ||
1510 | } | ||
1511 | |||
1457 | /* format_corename will inspect the pattern parameter, and output a | 1512 | /* format_corename will inspect the pattern parameter, and output a |
1458 | * name into corename, which must have space for at least | 1513 | * name into corename, which must have space for at least |
1459 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 1514 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
1460 | */ | 1515 | */ |
1461 | static int format_corename(char *corename, long signr) | 1516 | static int format_corename(struct core_name *cn, long signr) |
1462 | { | 1517 | { |
1463 | const struct cred *cred = current_cred(); | 1518 | const struct cred *cred = current_cred(); |
1464 | const char *pat_ptr = core_pattern; | 1519 | const char *pat_ptr = core_pattern; |
1465 | int ispipe = (*pat_ptr == '|'); | 1520 | int ispipe = (*pat_ptr == '|'); |
1466 | char *out_ptr = corename; | ||
1467 | char *const out_end = corename + CORENAME_MAX_SIZE; | ||
1468 | int rc; | ||
1469 | int pid_in_pattern = 0; | 1521 | int pid_in_pattern = 0; |
1522 | int err = 0; | ||
1523 | |||
1524 | cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); | ||
1525 | cn->corename = kmalloc(cn->size, GFP_KERNEL); | ||
1526 | cn->used = 0; | ||
1527 | |||
1528 | if (!cn->corename) | ||
1529 | return -ENOMEM; | ||
1470 | 1530 | ||
1471 | /* Repeat as long as we have more pattern to process and more output | 1531 | /* Repeat as long as we have more pattern to process and more output |
1472 | space */ | 1532 | space */ |
1473 | while (*pat_ptr) { | 1533 | while (*pat_ptr) { |
1474 | if (*pat_ptr != '%') { | 1534 | if (*pat_ptr != '%') { |
1475 | if (out_ptr == out_end) | 1535 | if (*pat_ptr == 0) |
1476 | goto out; | 1536 | goto out; |
1477 | *out_ptr++ = *pat_ptr++; | 1537 | err = cn_printf(cn, "%c", *pat_ptr++); |
1478 | } else { | 1538 | } else { |
1479 | switch (*++pat_ptr) { | 1539 | switch (*++pat_ptr) { |
1540 | /* single % at the end, drop that */ | ||
1480 | case 0: | 1541 | case 0: |
1481 | goto out; | 1542 | goto out; |
1482 | /* Double percent, output one percent */ | 1543 | /* Double percent, output one percent */ |
1483 | case '%': | 1544 | case '%': |
1484 | if (out_ptr == out_end) | 1545 | err = cn_printf(cn, "%c", '%'); |
1485 | goto out; | ||
1486 | *out_ptr++ = '%'; | ||
1487 | break; | 1546 | break; |
1488 | /* pid */ | 1547 | /* pid */ |
1489 | case 'p': | 1548 | case 'p': |
1490 | pid_in_pattern = 1; | 1549 | pid_in_pattern = 1; |
1491 | rc = snprintf(out_ptr, out_end - out_ptr, | 1550 | err = cn_printf(cn, "%d", |
1492 | "%d", task_tgid_vnr(current)); | 1551 | task_tgid_vnr(current)); |
1493 | if (rc > out_end - out_ptr) | ||
1494 | goto out; | ||
1495 | out_ptr += rc; | ||
1496 | break; | 1552 | break; |
1497 | /* uid */ | 1553 | /* uid */ |
1498 | case 'u': | 1554 | case 'u': |
1499 | rc = snprintf(out_ptr, out_end - out_ptr, | 1555 | err = cn_printf(cn, "%d", cred->uid); |
1500 | "%d", cred->uid); | ||
1501 | if (rc > out_end - out_ptr) | ||
1502 | goto out; | ||
1503 | out_ptr += rc; | ||
1504 | break; | 1556 | break; |
1505 | /* gid */ | 1557 | /* gid */ |
1506 | case 'g': | 1558 | case 'g': |
1507 | rc = snprintf(out_ptr, out_end - out_ptr, | 1559 | err = cn_printf(cn, "%d", cred->gid); |
1508 | "%d", cred->gid); | ||
1509 | if (rc > out_end - out_ptr) | ||
1510 | goto out; | ||
1511 | out_ptr += rc; | ||
1512 | break; | 1560 | break; |
1513 | /* signal that caused the coredump */ | 1561 | /* signal that caused the coredump */ |
1514 | case 's': | 1562 | case 's': |
1515 | rc = snprintf(out_ptr, out_end - out_ptr, | 1563 | err = cn_printf(cn, "%ld", signr); |
1516 | "%ld", signr); | ||
1517 | if (rc > out_end - out_ptr) | ||
1518 | goto out; | ||
1519 | out_ptr += rc; | ||
1520 | break; | 1564 | break; |
1521 | /* UNIX time of coredump */ | 1565 | /* UNIX time of coredump */ |
1522 | case 't': { | 1566 | case 't': { |
1523 | struct timeval tv; | 1567 | struct timeval tv; |
1524 | do_gettimeofday(&tv); | 1568 | do_gettimeofday(&tv); |
1525 | rc = snprintf(out_ptr, out_end - out_ptr, | 1569 | err = cn_printf(cn, "%lu", tv.tv_sec); |
1526 | "%lu", tv.tv_sec); | ||
1527 | if (rc > out_end - out_ptr) | ||
1528 | goto out; | ||
1529 | out_ptr += rc; | ||
1530 | break; | 1570 | break; |
1531 | } | 1571 | } |
1532 | /* hostname */ | 1572 | /* hostname */ |
1533 | case 'h': | 1573 | case 'h': |
1534 | down_read(&uts_sem); | 1574 | down_read(&uts_sem); |
1535 | rc = snprintf(out_ptr, out_end - out_ptr, | 1575 | err = cn_printf(cn, "%s", |
1536 | "%s", utsname()->nodename); | 1576 | utsname()->nodename); |
1537 | up_read(&uts_sem); | 1577 | up_read(&uts_sem); |
1538 | if (rc > out_end - out_ptr) | ||
1539 | goto out; | ||
1540 | out_ptr += rc; | ||
1541 | break; | 1578 | break; |
1542 | /* executable */ | 1579 | /* executable */ |
1543 | case 'e': | 1580 | case 'e': |
1544 | rc = snprintf(out_ptr, out_end - out_ptr, | 1581 | err = cn_printf(cn, "%s", current->comm); |
1545 | "%s", current->comm); | ||
1546 | if (rc > out_end - out_ptr) | ||
1547 | goto out; | ||
1548 | out_ptr += rc; | ||
1549 | break; | 1582 | break; |
1550 | /* core limit size */ | 1583 | /* core limit size */ |
1551 | case 'c': | 1584 | case 'c': |
1552 | rc = snprintf(out_ptr, out_end - out_ptr, | 1585 | err = cn_printf(cn, "%lu", |
1553 | "%lu", rlimit(RLIMIT_CORE)); | 1586 | rlimit(RLIMIT_CORE)); |
1554 | if (rc > out_end - out_ptr) | ||
1555 | goto out; | ||
1556 | out_ptr += rc; | ||
1557 | break; | 1587 | break; |
1558 | default: | 1588 | default: |
1559 | break; | 1589 | break; |
1560 | } | 1590 | } |
1561 | ++pat_ptr; | 1591 | ++pat_ptr; |
1562 | } | 1592 | } |
1593 | |||
1594 | if (err) | ||
1595 | return err; | ||
1563 | } | 1596 | } |
1597 | |||
1564 | /* Backward compatibility with core_uses_pid: | 1598 | /* Backward compatibility with core_uses_pid: |
1565 | * | 1599 | * |
1566 | * If core_pattern does not include a %p (as is the default) | 1600 | * If core_pattern does not include a %p (as is the default) |
1567 | * and core_uses_pid is set, then .%pid will be appended to | 1601 | * and core_uses_pid is set, then .%pid will be appended to |
1568 | * the filename. Do not do this for piped commands. */ | 1602 | * the filename. Do not do this for piped commands. */ |
1569 | if (!ispipe && !pid_in_pattern && core_uses_pid) { | 1603 | if (!ispipe && !pid_in_pattern && core_uses_pid) { |
1570 | rc = snprintf(out_ptr, out_end - out_ptr, | 1604 | err = cn_printf(cn, ".%d", task_tgid_vnr(current)); |
1571 | ".%d", task_tgid_vnr(current)); | 1605 | if (err) |
1572 | if (rc > out_end - out_ptr) | 1606 | return err; |
1573 | goto out; | ||
1574 | out_ptr += rc; | ||
1575 | } | 1607 | } |
1576 | out: | 1608 | out: |
1577 | *out_ptr = 0; | ||
1578 | return ispipe; | 1609 | return ispipe; |
1579 | } | 1610 | } |
1580 | 1611 | ||
@@ -1851,7 +1882,7 @@ static int umh_pipe_setup(struct subprocess_info *info) | |||
1851 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) | 1882 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
1852 | { | 1883 | { |
1853 | struct core_state core_state; | 1884 | struct core_state core_state; |
1854 | char corename[CORENAME_MAX_SIZE + 1]; | 1885 | struct core_name cn; |
1855 | struct mm_struct *mm = current->mm; | 1886 | struct mm_struct *mm = current->mm; |
1856 | struct linux_binfmt * binfmt; | 1887 | struct linux_binfmt * binfmt; |
1857 | const struct cred *old_cred; | 1888 | const struct cred *old_cred; |
@@ -1906,7 +1937,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1906 | */ | 1937 | */ |
1907 | clear_thread_flag(TIF_SIGPENDING); | 1938 | clear_thread_flag(TIF_SIGPENDING); |
1908 | 1939 | ||
1909 | ispipe = format_corename(corename, signr); | 1940 | ispipe = format_corename(&cn, signr); |
1941 | |||
1942 | if (ispipe == -ENOMEM) { | ||
1943 | printk(KERN_WARNING "format_corename failed\n"); | ||
1944 | printk(KERN_WARNING "Aborting core\n"); | ||
1945 | goto fail_corename; | ||
1946 | } | ||
1910 | 1947 | ||
1911 | if (ispipe) { | 1948 | if (ispipe) { |
1912 | int dump_count; | 1949 | int dump_count; |
@@ -1943,7 +1980,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1943 | goto fail_dropcount; | 1980 | goto fail_dropcount; |
1944 | } | 1981 | } |
1945 | 1982 | ||
1946 | helper_argv = argv_split(GFP_KERNEL, corename+1, NULL); | 1983 | helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL); |
1947 | if (!helper_argv) { | 1984 | if (!helper_argv) { |
1948 | printk(KERN_WARNING "%s failed to allocate memory\n", | 1985 | printk(KERN_WARNING "%s failed to allocate memory\n", |
1949 | __func__); | 1986 | __func__); |
@@ -1956,7 +1993,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1956 | argv_free(helper_argv); | 1993 | argv_free(helper_argv); |
1957 | if (retval) { | 1994 | if (retval) { |
1958 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1995 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1959 | corename); | 1996 | cn.corename); |
1960 | goto close_fail; | 1997 | goto close_fail; |
1961 | } | 1998 | } |
1962 | } else { | 1999 | } else { |
@@ -1965,7 +2002,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1965 | if (cprm.limit < binfmt->min_coredump) | 2002 | if (cprm.limit < binfmt->min_coredump) |
1966 | goto fail_unlock; | 2003 | goto fail_unlock; |
1967 | 2004 | ||
1968 | cprm.file = filp_open(corename, | 2005 | cprm.file = filp_open(cn.corename, |
1969 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 2006 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1970 | 0600); | 2007 | 0600); |
1971 | if (IS_ERR(cprm.file)) | 2008 | if (IS_ERR(cprm.file)) |
@@ -2007,6 +2044,8 @@ fail_dropcount: | |||
2007 | if (ispipe) | 2044 | if (ispipe) |
2008 | atomic_dec(&core_dump_count); | 2045 | atomic_dec(&core_dump_count); |
2009 | fail_unlock: | 2046 | fail_unlock: |
2047 | kfree(cn.corename); | ||
2048 | fail_corename: | ||
2010 | coredump_finish(mm); | 2049 | coredump_finish(mm); |
2011 | revert_creds(old_cred); | 2050 | revert_creds(old_cred); |
2012 | fail_creds: | 2051 | fail_creds: |