Commit 2c4cb043 authored by Omar Sandoval's avatar Omar Sandoval Committed by Al Viro

coredump: only charge written data against RLIMIT_CORE

Commit 9b56d543 ("dump_skip(): dump_seek() replacement taking
coredump_params") introduced a regression with regard to RLIMIT_CORE.
Previously, when a core dump was sparse, only the data that was actually
written out would count against the limit. Now, the sparse ranges are
also included, which leads to truncated core dumps when the actual disk
usage is still well below the limit. Restore the old behavior by only
counting what gets emitted and ignoring what gets skipped.
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a0083939
...@@ -782,7 +782,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr) ...@@ -782,7 +782,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
struct file *file = cprm->file; struct file *file = cprm->file;
loff_t pos = file->f_pos; loff_t pos = file->f_pos;
ssize_t n; ssize_t n;
if (pos + nr > cprm->limit) if (cprm->written + nr > cprm->limit)
return 0; return 0;
while (nr) { while (nr) {
if (dump_interrupted()) if (dump_interrupted())
...@@ -791,6 +791,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr) ...@@ -791,6 +791,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
if (n <= 0) if (n <= 0)
return 0; return 0;
file->f_pos = pos; file->f_pos = pos;
cprm->written += n;
nr -= n; nr -= n;
} }
return 1; return 1;
...@@ -802,8 +803,6 @@ int dump_skip(struct coredump_params *cprm, size_t nr) ...@@ -802,8 +803,6 @@ int dump_skip(struct coredump_params *cprm, size_t nr)
static char zeroes[PAGE_SIZE]; static char zeroes[PAGE_SIZE];
struct file *file = cprm->file; struct file *file = cprm->file;
if (file->f_op->llseek && file->f_op->llseek != no_llseek) { if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
if (file->f_pos + nr > cprm->limit)
return 0;
if (dump_interrupted() || if (dump_interrupted() ||
file->f_op->llseek(file, nr, SEEK_CUR) < 0) file->f_op->llseek(file, nr, SEEK_CUR) < 0)
return 0; return 0;
......
...@@ -64,6 +64,7 @@ struct coredump_params { ...@@ -64,6 +64,7 @@ struct coredump_params {
struct file *file; struct file *file;
unsigned long limit; unsigned long limit;
unsigned long mm_flags; unsigned long mm_flags;
loff_t written;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment