patch-2.3.12 linux/fs/exec.c

Next file: linux/fs/fcntl.c
Previous file: linux/fs/buffer.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.11/linux/fs/exec.c linux/fs/exec.c
@@ -371,7 +371,6 @@
 	if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
 		flush_cache_mm(old_mm);
 		mm_release();
-		release_segments(old_mm);
 		exit_mmap(old_mm);
 		flush_tlb_mm(old_mm);
 		return 0;
@@ -379,26 +378,19 @@
 
 	mm = mm_alloc();
 	if (mm) {
-		mm->cpu_vm_mask = (1UL << smp_processor_id());
-		mm->total_vm = 0;
-		mm->rss = 0;
-		mm->pgd = pgd_alloc();
-		if (mm->pgd) {
-			struct mm_struct *active_mm = current->active_mm;
-
-			current->mm = mm;
-			current->active_mm = mm;
-			SET_PAGE_DIR(current, mm->pgd);
-			activate_context(current);
-			mm_release();
-			if (old_mm) {
-				mmput(old_mm);
-				return 0;
-			}
-			mmdrop(active_mm);
+		struct mm_struct *active_mm = current->active_mm;
+
+		current->mm = mm;
+		current->active_mm = mm;
+		switch_mm(active_mm, mm, smp_processor_id());
+		mm_release();
+		if (old_mm) {
+			if (active_mm != old_mm) BUG();
+			mmput(old_mm);
 			return 0;
 		}
-		kmem_cache_free(mm_cachep, mm);
+		mmdrop(active_mm);
+		return 0;
 	}
 	return -ENOMEM;
 }
@@ -455,9 +447,9 @@
 		unsigned long set, i;
 
 		i = j * __NFDBITS;
-		if (i >= files->max_fds)
+		if (i >= files->max_fds || i >= files->max_fdset)
 			break;
-		set = xchg(&files->close_on_exec.fds_bits[j], 0);
+		set = xchg(&files->close_on_exec->fds_bits[j], 0);
 		j++;
 		for ( ; set ; i++,set >>= 1) {
 			if (set & 1)
@@ -836,4 +828,54 @@
 		free_page(bprm.page[i]);
 
 	return retval;
+}
+
+int do_coredump(long signr, struct pt_regs * regs)
+{
+	struct linux_binfmt * binfmt;
+	char corename[6+sizeof(current->comm)];
+	struct file * file;
+	struct dentry * dentry;
+	struct inode * inode;
+
+	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;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)