Re: [2.3.11=pre6]: No OOPS, but mount segfaults remounting "/"?

Alexander Viro (viro@math.psu.edu)
Wed, 21 Jul 1999 21:07:20 -0400 (EDT)


On Wed, 21 Jul 1999, Linus Torvalds wrote:

> > Another thing: checks in binfmt_{elf,aout,whatnot}.c (is it dumpable?)
> > should go into the top-level code. Otherwise we'll spend the eternity
> > trying to resync all copies. I'll do it if you have no objections.
>
> Sure.

There we go:
* new function added: int do_coredump(signr, regs);
* signal dispatching code uses it now.
* new field added to struct linux_binfmt - min_coredump.
It's a minimal coredump size. Drive rlimit below it and
dumps are blocked.
* checks for process being dumpable (identical everywhere
except the irix_core_dump, which failed to check for
shared VM context) moved to do_coredump()
* rlimit check went the same way.
* creating the core file and sanity checks - ditto.
* same for closing the core afterwards.
* ->core_dump() method got an additional parameter -
file to dump into.
* All instances of struct binfmt_struct updated.

Methink it became much saner now.
Cheers,
Al
Patch follows:
diff -urN linux-2.3.11-pre8/arch/alpha/kernel/signal.c linux-bird.dump/arch/alpha/kernel/signal.c
--- linux-2.3.11-pre8/arch/alpha/kernel/signal.c Tue Jul 6 04:30:23 1999
+++ linux-bird.dump/arch/alpha/kernel/signal.c Wed Jul 21 18:20:08 1999
@@ -688,12 +688,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/arm/kernel/signal.c linux-bird.dump/arch/arm/kernel/signal.c
--- linux-2.3.11-pre8/arch/arm/kernel/signal.c Mon Jun 21 14:09:15 1999
+++ linux-bird.dump/arch/arm/kernel/signal.c Wed Jul 21 18:20:39 1999
@@ -543,12 +543,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/i386/kernel/signal.c linux-bird.dump/arch/i386/kernel/signal.c
--- linux-2.3.11-pre8/arch/i386/kernel/signal.c Wed Jul 21 16:27:57 1999
+++ linux-bird.dump/arch/i386/kernel/signal.c Wed Jul 21 18:21:11 1999
@@ -687,12 +687,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/m68k/kernel/signal.c linux-bird.dump/arch/m68k/kernel/signal.c
--- linux-2.3.11-pre8/arch/m68k/kernel/signal.c Mon Jun 21 12:35:55 1999
+++ linux-bird.dump/arch/m68k/kernel/signal.c Wed Jul 21 18:22:00 1999
@@ -1084,9 +1084,7 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGIOT: case SIGFPE: case SIGSEGV:
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */

diff -urN linux-2.3.11-pre8/arch/mips/kernel/irixelf.c linux-bird.dump/arch/mips/kernel/irixelf.c
--- linux-2.3.11-pre8/arch/mips/kernel/irixelf.c Wed Jul 21 16:27:57 1999
+++ linux-bird.dump/arch/mips/kernel/irixelf.c Wed Jul 21 20:34:45 1999
@@ -48,11 +48,13 @@
extern int dump_fpu (elf_fpregset_t *);

static struct linux_binfmt irix_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_irix_binary, load_irix_library, irix_core_dump
+ NULL,
#else
- NULL, &__this_module.usecount, load_irix_binary, load_irix_library, irix_core_dump
+ &__this_module.usecount,
#endif
+ load_irix_binary, load_irix_library, irix_core_dump, PAGE_SIZE
};

#ifndef elf_addr_t
@@ -1105,24 +1107,20 @@

#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(off) \
if (!dump_seek(file, (off))) \
- goto close_coredump;
+ goto end_coredump;
/* Actual dumper.
*
* This is a two-pass process; first we find the offsets of the bits,
* and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int irix_core_dump(long signr, struct pt_regs * regs)
+static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
int has_dumped = 0;
- struct file *file;
- struct dentry *dentry;
- struct inode *inode;
mm_segment_t fs;
- char corefile[6+sizeof(current->comm)];
int segs;
int i;
size_t size;
@@ -1135,10 +1133,6 @@
struct elf_prstatus prstatus; /* NT_PRSTATUS */
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
-
- if (!current->dumpable || limit < PAGE_SIZE)
- return 0;
- current->dumpable = 0;

#ifndef CONFIG_BINFMT_IRIX
MOD_INC_USE_COUNT;
@@ -1188,27 +1182,6 @@
fs = get_fs();
set_fs(KERNEL_DS);

- memcpy(corefile,"core.", 5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (inode->i_nlink > 1)
- goto close_coredump; /* multiple links - don't dump */
-
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
-
has_dumped = 1;
current->flags |= PF_DUMPCORE;

@@ -1345,7 +1318,7 @@

for(i = 0; i < numnote; i++)
if (!writenote(&notes[i], file))
- goto close_coredump;
+ goto end_coredump;

set_fs(fs);

@@ -1371,9 +1344,6 @@
printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
(off_t) file->f_pos, offset);
}
-
- close_coredump:
- filp_close(file, NULL);

end_coredump:
set_fs(fs);
diff -urN linux-2.3.11-pre8/arch/mips/kernel/irixsig.c linux-bird.dump/arch/mips/kernel/irixsig.c
--- linux-2.3.11-pre8/arch/mips/kernel/irixsig.c Sat Jun 26 16:40:11 1999
+++ linux-bird.dump/arch/mips/kernel/irixsig.c Wed Jul 21 18:22:25 1999
@@ -261,12 +261,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/mips/kernel/signal.c linux-bird.dump/arch/mips/kernel/signal.c
--- linux-2.3.11-pre8/arch/mips/kernel/signal.c Sat Jun 26 16:40:12 1999
+++ linux-bird.dump/arch/mips/kernel/signal.c Wed Jul 21 18:22:49 1999
@@ -493,12 +493,8 @@
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/ppc/kernel/signal.c linux-bird.dump/arch/ppc/kernel/signal.c
--- linux-2.3.11-pre8/arch/ppc/kernel/signal.c Wed Jun 30 16:56:47 1999
+++ linux-bird.dump/arch/ppc/kernel/signal.c Wed Jul 21 18:23:07 1999
@@ -444,12 +444,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */

default:
diff -urN linux-2.3.11-pre8/arch/sparc/kernel/signal.c linux-bird.dump/arch/sparc/kernel/signal.c
--- linux-2.3.11-pre8/arch/sparc/kernel/signal.c Mon Jun 21 14:09:49 1999
+++ linux-bird.dump/arch/sparc/kernel/signal.c Wed Jul 21 18:40:25 1999
@@ -1160,14 +1160,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt &&
- current->binfmt->core_dump &&
- current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
diff -urN linux-2.3.11-pre8/arch/sparc64/kernel/binfmt_aout32.c linux-bird.dump/arch/sparc64/kernel/binfmt_aout32.c
--- linux-2.3.11-pre8/arch/sparc64/kernel/binfmt_aout32.c Fri Jul 2 21:17:54 1999
+++ linux-bird.dump/arch/sparc64/kernel/binfmt_aout32.c Wed Jul 21 20:22:58 1999
@@ -39,7 +39,8 @@
extern void dump_thread(struct pt_regs *, struct user *);

static struct linux_binfmt aout32_format = {
- NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump
+ NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump,
+ PAGE_SIZE
};

static void set_brk(unsigned long start, unsigned long end)
@@ -63,12 +64,12 @@

#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (void *)(addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;

#define DUMP_SEEK(offset) \
if (file->f_op->llseek) { \
if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto close_coredump; \
+ goto end_coredump; \
} else file->f_pos = (offset)

/*
@@ -82,45 +83,17 @@
*/

static inline int
-do_aout32_core_dump(long signr, struct pt_regs * regs)
+do_aout32_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
- struct dentry * dentry = NULL;
- struct inode * inode = NULL;
- struct file * file;
mm_segment_t fs;
int has_dumped = 0;
- char corefile[6+sizeof(current->comm)];
unsigned long dump_start, dump_size;
struct user dump;
# define START_DATA(u) (u.u_tsize)
# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))

- if (!current->dumpable || atomic_read(&current->mm->count) != 1)
- return 0;
- current->dumpable = 0;
-
-/* See if we have enough room to write the upage. */
- if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
- return 0;
fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile,O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(current->comm));
@@ -165,20 +138,18 @@
/* Finally dump the task struct. Not be used by gdb, but could be useful */
set_fs(KERNEL_DS);
DUMP_WRITE(current,sizeof(*current));
-close_coredump:
- filp_close(file, NULL);
end_coredump:
set_fs(fs);
return has_dumped;
}

static int
-aout32_core_dump(long signr, struct pt_regs * regs)
+aout32_core_dump(long signr, struct pt_regs * regs, struct file * file)
{
int retval;

MOD_INC_USE_COUNT;
- retval = do_aout32_core_dump(signr, regs);
+ retval = do_aout32_core_dump(signr, regs, file);
MOD_DEC_USE_COUNT;
return retval;
}
diff -urN linux-2.3.11-pre8/arch/sparc64/kernel/signal.c linux-bird.dump/arch/sparc64/kernel/signal.c
--- linux-2.3.11-pre8/arch/sparc64/kernel/signal.c Mon Jun 21 14:09:56 1999
+++ linux-bird.dump/arch/sparc64/kernel/signal.c Wed Jul 21 18:42:37 1999
@@ -866,12 +866,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug the dynamic linker */
printk ("Sig %d going...\n", (int)signr);
diff -urN linux-2.3.11-pre8/arch/sparc64/kernel/signal32.c linux-bird.dump/arch/sparc64/kernel/signal32.c
--- linux-2.3.11-pre8/arch/sparc64/kernel/signal32.c Mon Jun 21 14:09:56 1999
+++ linux-bird.dump/arch/sparc64/kernel/signal32.c Wed Jul 21 19:04:40 1999
@@ -1291,14 +1291,8 @@

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt &&
- current->binfmt->core_dump &&
- current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
diff -urN linux-2.3.11-pre8/fs/binfmt_aout.c linux-bird.dump/fs/binfmt_aout.c
--- linux-2.3.11-pre8/fs/binfmt_aout.c Wed Jul 21 16:28:02 1999
+++ linux-bird.dump/fs/binfmt_aout.c Wed Jul 21 20:25:43 1999
@@ -36,11 +36,13 @@
extern void dump_thread(struct pt_regs *, struct user *);

static struct linux_binfmt aout_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_aout_binary, load_aout_library, aout_core_dump
+ NULL,
#else
- NULL, &__this_module, load_aout_binary, load_aout_library, aout_core_dump
+ &__this_module,
#endif
+ load_aout_binary, load_aout_library, aout_core_dump, PAGE_SIZE
};

static void set_brk(unsigned long start, unsigned long end)
@@ -64,12 +66,12 @@

#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (void *)(addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;

#define DUMP_SEEK(offset) \
if (file->f_op->llseek) { \
if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto close_coredump; \
+ goto end_coredump; \
} else file->f_pos = (offset)

/*
@@ -83,14 +85,10 @@
*/

static inline int
-do_aout_core_dump(long signr, struct pt_regs * regs)
+do_aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
- struct dentry * dentry = NULL;
- struct inode * inode = NULL;
- struct file * file;
mm_segment_t fs;
int has_dumped = 0;
- char corefile[6+sizeof(current->comm)];
unsigned long dump_start, dump_size;
struct user dump;
#if defined(__alpha__)
@@ -106,32 +104,8 @@
# define START_STACK(u) (u.start_stack)
#endif

- if (!current->dumpable || atomic_read(&current->mm->mm_users) != 1)
- return 0;
- current->dumpable = 0;
-
-/* See if we have enough room to write the upage. */
- if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
- return 0;
fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile,O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(current->comm));
@@ -210,20 +184,18 @@
/* Finally dump the task struct. Not be used by gdb, but could be useful */
set_fs(KERNEL_DS);
DUMP_WRITE(current,sizeof(*current));
-close_coredump:
- filp_close(file, NULL);
end_coredump:
set_fs(fs);
return has_dumped;
}

static int
-aout_core_dump(long signr, struct pt_regs * regs)
+aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
int retval;

MOD_INC_USE_COUNT;
- retval = do_aout_core_dump(signr, regs);
+ retval = do_aout_core_dump(signr, regs, file);
MOD_DEC_USE_COUNT;
return retval;
}
diff -urN linux-2.3.11-pre8/fs/binfmt_elf.c linux-bird.dump/fs/binfmt_elf.c
--- linux-2.3.11-pre8/fs/binfmt_elf.c Wed Jul 21 16:28:02 1999
+++ linux-bird.dump/fs/binfmt_elf.c Wed Jul 21 20:28:27 1999
@@ -64,11 +64,13 @@
#define ELF_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))

static struct linux_binfmt elf_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_elf_binary, load_elf_library, elf_core_dump
+ NULL,
#else
- NULL, &__this_module, load_elf_binary, load_elf_library, elf_core_dump
+ &__this_module,
#endif
+ load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
};

static void set_brk(unsigned long start, unsigned long end)
@@ -1026,10 +1028,10 @@

#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(off) \
if (!dump_seek(file, (off))) \
- goto close_coredump;
+ goto end_coredump;
/*
* Actual dumper
*
@@ -1037,14 +1039,10 @@
* and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int elf_core_dump(long signr, struct pt_regs * regs)
+static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
{
int has_dumped = 0;
- struct file *file;
- struct dentry *dentry;
- struct inode *inode;
mm_segment_t fs;
- char corefile[6+sizeof(current->comm)];
int segs;
int i;
size_t size;
@@ -1058,12 +1056,6 @@
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */

- if (!current->dumpable ||
- limit < ELF_EXEC_PAGESIZE ||
- atomic_read(&current->mm->mm_users) != 1)
- return 0;
- current->dumpable = 0;
-
#ifndef CONFIG_BINFMT_ELF
MOD_INC_USE_COUNT;
#endif
@@ -1112,27 +1104,6 @@
fs = get_fs();
set_fs(KERNEL_DS);

- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (inode->i_nlink > 1)
- goto close_coredump; /* multiple links - don't dump */
-
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
-
has_dumped = 1;
current->flags |= PF_DUMPCORE;

@@ -1289,7 +1260,7 @@

for(i = 0; i < numnote; i++)
if (!writenote(&notes[i], file))
- goto close_coredump;
+ goto end_coredump;

set_fs(fs);

@@ -1315,9 +1286,6 @@
printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
(off_t) file->f_pos, offset);
}
-
- close_coredump:
- filp_close(file, NULL);

end_coredump:
set_fs(fs);
diff -urN linux-2.3.11-pre8/fs/binfmt_em86.c linux-bird.dump/fs/binfmt_em86.c
--- linux-2.3.11-pre8/fs/binfmt_em86.c Mon Jun 21 13:30:14 1999
+++ linux-bird.dump/fs/binfmt_em86.c Wed Jul 21 19:54:09 1999
@@ -105,11 +105,13 @@
}

struct linux_binfmt em86_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_em86, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_em86, NULL, NULL
+ &__this_module,
#endif
+ load_em86, NULL, NULL, 0
};

int __init init_em86_binfmt(void)
diff -urN linux-2.3.11-pre8/fs/binfmt_misc.c linux-bird.dump/fs/binfmt_misc.c
--- linux-2.3.11-pre8/fs/binfmt_misc.c Mon Jun 21 13:30:14 1999
+++ linux-bird.dump/fs/binfmt_misc.c Wed Jul 21 19:54:40 1999
@@ -64,11 +64,13 @@
static int entry_proc_setup(struct binfmt_entry *e);

static struct linux_binfmt misc_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_misc_binary, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_misc_binary, NULL, NULL
+ &__this_module,
#endif
+ load_misc_binary, NULL, NULL, 0
};

static struct proc_dir_entry *bm_dir = NULL;
diff -urN linux-2.3.11-pre8/fs/binfmt_script.c linux-bird.dump/fs/binfmt_script.c
--- linux-2.3.11-pre8/fs/binfmt_script.c Mon Jun 21 13:30:14 1999
+++ linux-bird.dump/fs/binfmt_script.c Wed Jul 21 19:55:17 1999
@@ -101,11 +101,13 @@
}

struct linux_binfmt script_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_script, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_script, NULL, NULL
+ &__this_module,
#endif
+ load_script, NULL, NULL, 0
};

int __init init_script_binfmt(void)
diff -urN linux-2.3.11-pre8/fs/exec.c linux-bird.dump/fs/exec.c
--- linux-2.3.11-pre8/fs/exec.c Wed Jul 21 16:28:02 1999
+++ linux-bird.dump/fs/exec.c Wed Jul 21 20:01:33 1999
@@ -837,3 +837,49 @@

return retval;
}
+
+int do_coredump(unsigned long signr, struct pt_regs * regs) {
+ struct linux_binfmt * binmft;
+ char corename[6+sizeof(current->comm)];
+ struct file * file;
+ lock_kernel();
+ binfmt = current->binfmt;
+ if (!binfmt || !binfmt->core_dump)
+ goto fail;
+ if (!current->dumpable || atomic_read(&current->mm->mm_users) != 1)
+ current->dumpable = 0;
+ if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
+ goto fail;
+
+ memcpy(corename,"core.", 5);
+#if 0
+ memcpy(corename+5,current->comm,sizeof(current->comm));
+#else
+ corename[4] = '\0';
+#endif
+ file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
+ if (IS_ERR(file))
+ goto fail;
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
+ if (inode->i_nlink > 1)
+ goto close_fail; /* multiple links - don't dump */
+
+ if (!S_ISREG(inode->i_mode))
+ goto close_fail;
+ if (!inode->i_op || !inode->i_op->default_file_ops)
+ goto close_fail;
+ if (!file->f_op->write)
+ goto close_fail;
+ if (!binfmt->core_dump(signr, regs, file))
+ goto close_fail;
+ filp_close(file, NULL);
+ unlock_kernel();
+ return 1;
+
+close_fail:
+ filp_close(file, NULL);
+fail:
+ unlock_kernel();
+ return 0;
+}
diff -urN linux-2.3.11-pre8/include/linux/binfmts.h linux-bird.dump/include/linux/binfmts.h
--- linux-2.3.11-pre8/include/linux/binfmts.h Sat Jun 26 16:43:42 1999
+++ linux-bird.dump/include/linux/binfmts.h Wed Jul 21 20:35:16 1999
@@ -38,7 +38,8 @@
struct module *module;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(int fd);
- int (*core_dump)(long signr, struct pt_regs * regs);
+ int (*core_dump)(long signr, struct pt_regs * regs, struct file * file);
+ unsigned long min_coredump; /* minimal dump size */
};

extern int register_binfmt(struct linux_binfmt *);
@@ -66,6 +67,7 @@
extern int copy_strings(int argc,char ** argv,struct linux_binprm *bprm);
extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
extern void compute_creds(struct linux_binprm *binprm);
+extern int do_coredump(long signr, struct pt_regs * regs);


#if 0

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/