diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/coredump.c | 19 |
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 | ||
47 | int core_uses_pid; | 47 | int core_uses_pid; |
48 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | ||
49 | unsigned int core_pipe_limit; | 48 | unsigned int core_pipe_limit; |
49 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | ||
50 | static int core_name_size = CORENAME_MAX_SIZE; | ||
50 | 51 | ||
51 | struct core_name { | 52 | struct core_name { |
52 | char *corename; | 53 | char *corename; |
53 | int used, size; | 54 | int used, size; |
54 | }; | 55 | }; |
55 | static 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 | ||
59 | static int expand_corename(struct core_name *cn) | 59 | static 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 |