aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/coredump.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/fs/coredump.c b/fs/coredump.c
index 90d7cee54347..56a9ab963a40 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -45,26 +45,28 @@
45#include <trace/events/sched.h> 45#include <trace/events/sched.h>
46 46
47int core_uses_pid; 47int core_uses_pid;
48char core_pattern[CORENAME_MAX_SIZE] = "core";
49unsigned int core_pipe_limit; 48unsigned int core_pipe_limit;
49char core_pattern[CORENAME_MAX_SIZE] = "core";
50static int core_name_size = CORENAME_MAX_SIZE;
50 51
51struct core_name { 52struct core_name {
52 char *corename; 53 char *corename;
53 int used, size; 54 int used, size;
54}; 55};
55static atomic_t call_count = ATOMIC_INIT(1);
56 56
57/* The maximal length of core_pattern is also specified in sysctl.c */ 57/* The maximal length of core_pattern is also specified in sysctl.c */
58 58
59static int expand_corename(struct core_name *cn) 59static int expand_corename(struct core_name *cn, int size)
60{ 60{
61 int size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count);
62 char *corename = krealloc(cn->corename, size, GFP_KERNEL); 61 char *corename = krealloc(cn->corename, size, GFP_KERNEL);
63 62
64 if (!corename) 63 if (!corename)
65 return -ENOMEM; 64 return -ENOMEM;
66 65
67 cn->size = size; 66 if (size > core_name_size) /* racy but harmless */
67 core_name_size = size;
68
69 cn->size = ksize(corename);
68 cn->corename = corename; 70 cn->corename = corename;
69 return 0; 71 return 0;
70} 72}
@@ -81,7 +83,7 @@ again:
81 return 0; 83 return 0;
82 } 84 }
83 85
84 if (!expand_corename(cn)) 86 if (!expand_corename(cn, cn->size + need - free + 1))
85 goto again; 87 goto again;
86 88
87 return -ENOMEM; 89 return -ENOMEM;
@@ -160,9 +162,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
160 int err = 0; 162 int err = 0;
161 163
162 cn->used = 0; 164 cn->used = 0;
163 cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); 165 cn->corename = NULL;
164 cn->corename = kmalloc(cn->size, GFP_KERNEL); 166 if (expand_corename(cn, core_name_size))
165 if (!cn->corename)
166 return -ENOMEM; 167 return -ENOMEM;
167 168
168 /* Repeat as long as we have more pattern to process and more output 169 /* Repeat as long as we have more pattern to process and more output