[Linux-HA] Heartbeat always restarts (performingrestart exec)sinceipfail w

Lars Marowsky-Bree lmb at suse.de
Fri Jul 8 02:31:07 MDT 2005


On 2005-07-08T09:09:03, Anquijix Schiptara <anquijix at hotmail.com> wrote:

> I dont have this suid_dumpable file. But i installed heartbeat as rpm 
> package. How to recompile that?

For that, you need a kernel patch. I've attached it. You may need to
adapt it to your specific kernel version.



Sincerely,
    Lars Marowsky-Brée <lmb at suse.de>

-- 
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business	 -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"

-------------- next part --------------
From: Alan Cox <alan at lxorguk.ukuu.org.uk>
Subject: setuid core dump
References: 78568

This fixes the /proc problems that were pointed out in the original. I've
left the values numeric since I think the code actually reads better in
that form, but thats open for debate.


Acked-by: Andrea Arcangeli <andrea at suse.de>
Signed-off-by: Lars Marowsky-Bree <lmb at suse.de>

Index: linux-2.6.5/Documentation/sysctl/kernel.txt
===================================================================
--- linux-2.6.5.orig/Documentation/sysctl/kernel.txt	2005-04-20 23:19:06.234830085 +0200
+++ linux-2.6.5/Documentation/sysctl/kernel.txt	2005-04-20 23:42:38.871541227 +0200
@@ -50,6 +50,7 @@ show up in /proc/sys/kernel:
 - shmmax                      [ sysv ipc ]
 - shmmni
 - stop-a                      [ SPARC only ]
+- suid_dumpable
 - sysrq                       ==> Documentation/sysrq.txt
 - tainted
 - threads-max
@@ -310,6 +311,25 @@ kernel.  This value defaults to SHMMAX.
 
 ==============================================================
 
+suid_dumpable:
+
+This value can be used to query and set the core dump mode for setuid
+or otherwise protected/tainted binaries. The modes are
+
+0 - (default) - traditional behaviour. Any process which has changed
+	privilege levels or is execute only will not be dumped
+1 - (debug) - all processes dump core when possible. The core dump is
+	owned by the current user and no security is applied. This is
+	intended for system debugging situations only.
+2 - (suidsafe) - any binary which normally not be dumped is dumped
+	readable by root only. This allows the end user to remove
+	such a dump but not access it directly. For security reasons
+	core dumps in this mode will not overwrite one another or 
+	other files. This mode is appropriate when adminstrators are
+	attempting to debug problems in a normal environment.
+
+==============================================================
+
 tainted: 
 
 Non-zero if the kernel has been tainted.  Numeric values, which
Index: linux-2.6.5/fs/exec.c
===================================================================
--- linux-2.6.5.orig/fs/exec.c	2005-04-20 23:19:25.829432088 +0200
+++ linux-2.6.5/fs/exec.c	2005-04-20 23:44:19.408685450 +0200
@@ -67,6 +67,8 @@ EXPORT_SYMBOL(coredump_notifier_list);
 
 int core_uses_pid;
 char core_pattern[65] = "core";
+int suid_dumpable = 0;
+
 /* The maximal length of core_pattern is also specified in sysctl.c */
 
 static struct linux_binfmt *formats;
@@ -863,6 +865,9 @@ int flush_old_exec(struct linux_binprm *
 
 	if (current->euid == current->uid && current->egid == current->gid)
 		current->mm->dumpable = 1;
+	else
+		current->mm->dumpable = suid_dumpable;
+		
 	name = bprm->filename;
 	for (i=0; (ch = *(name++)) != '\0';) {
 		if (ch == '/')
@@ -878,7 +883,7 @@ int flush_old_exec(struct linux_binprm *
 	if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 	    permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
 	    (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP))
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 
 	/* An exec changes our domain. We are no longer part of the thread
 	   group */
@@ -1422,7 +1427,9 @@ int do_coredump(long signr, int exit_cod
 	struct inode * inode;
 	struct file * file;
 	int retval = 0;
-
+	int fsuid = current->fsuid;
+	int flag = 0;
+	
 	notifier_call_chain(&coredump_notifier_list , 0 , current);
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
@@ -1432,6 +1439,17 @@ int do_coredump(long signr, int exit_cod
 		up_write(&mm->mmap_sem);
 		goto fail;
 	}
+	
+	/*
+	 *	We cannot trust fsuid as being the "true" uid of the
+	 *	process nor do we know its entire history. We only know it
+	 *	was tainted so we dump it as root in mode 2.
+	 */
+	if (mm->dumpable == 2)		/* Setuid core dump mode */
+	{
+		flag = O_EXCL;		/* Stop rewrite attacks */
+		current->fsuid = 0;	/* Dump root private */
+	}
 	mm->dumpable = 0;
 	init_completion(&mm->core_done);
 	current->signal->group_exit = 1;
@@ -1448,7 +1466,7 @@ int do_coredump(long signr, int exit_cod
  	lock_kernel();
 	format_corename(corename, core_pattern, signr);
 	unlock_kernel();
-	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600);
+	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600);
 	if (IS_ERR(file))
 		goto fail_unlock;
 	inode = file->f_dentry->d_inode;
@@ -1472,6 +1490,7 @@ int do_coredump(long signr, int exit_cod
 close_fail:
 	filp_close(file, NULL);
 fail_unlock:
+	current->fsuid = fsuid;
 	complete_all(&mm->core_done);
 fail:
 	return retval;
Index: linux-2.6.5/fs/proc/base.c
===================================================================
--- linux-2.6.5.orig/fs/proc/base.c	2005-04-20 23:19:26.619335581 +0200
+++ linux-2.6.5/fs/proc/base.c	2005-04-20 23:42:38.880539879 +0200
@@ -336,7 +336,7 @@ static int may_ptrace_attach(struct task
 	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
 		goto out;
 	rmb();
-	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
+	if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
 		goto out;
 	if (security_ptrace(current, task))
 		goto out;
@@ -1066,7 +1066,9 @@ static int task_dumpable(struct task_str
 	if (mm)
 		dumpable = mm->dumpable;
 	task_unlock(task);
-	return dumpable;
+	if(dumpable == 1)
+		return 1;
+	return 0;
 }
 
 
Index: linux-2.6.5/include/linux/binfmts.h
===================================================================
--- linux-2.6.5.orig/include/linux/binfmts.h	2005-04-20 23:19:12.517060414 +0200
+++ linux-2.6.5/include/linux/binfmts.h	2005-04-20 23:42:38.882539579 +0200
@@ -69,6 +69,8 @@ extern void remove_arg_zero(struct linux
 extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
 extern int flush_old_exec(struct linux_binprm * bprm);
 
+extern int suid_dumpable;
+
 /* Stack area protections */
 #define EXSTACK_DEFAULT   0	/* Whatever the arch defaults to */
 #define EXSTACK_DISABLE_X 1	/* Disable executable stacks */
Index: linux-2.6.5/include/linux/sched.h
===================================================================
--- linux-2.6.5.orig/include/linux/sched.h	2005-04-20 23:19:33.193532831 +0200
+++ linux-2.6.5/include/linux/sched.h	2005-04-20 23:45:55.372842066 +0200
@@ -221,7 +221,7 @@ struct mm_struct {
 
 	unsigned long saved_auxv[40]; /* for /proc/PID/auxv */
 
-	unsigned dumpable:1;
+	unsigned dumpable:2;
 #ifdef CONFIG_HUGETLB_PAGE
 	int used_hugetlb;
 #endif
Index: linux-2.6.5/include/linux/sysctl.h
===================================================================
--- linux-2.6.5.orig/include/linux/sysctl.h	2005-04-20 23:19:32.859573589 +0200
+++ linux-2.6.5/include/linux/sysctl.h	2005-04-20 23:46:36.775956257 +0200
@@ -142,6 +142,7 @@ enum
 	KERN_HPAGES_MAP_SZ=72,  /* int: min size (MB) of mapping */
 	KERN_XMON=73,		/* int: xmon debugger enabled */
 	KERN_UNSUPPORTED=74,	/* int: allow loading of unsupported modules */
+	KERN_SETUID_DUMPABLE=75,	/* int: behaviour of dumps for setuid core */
 
 };
 
Index: linux-2.6.5/kernel/sys.c
===================================================================
--- linux-2.6.5.orig/kernel/sys.c	2005-04-20 23:19:22.938785362 +0200
+++ linux-2.6.5/kernel/sys.c	2005-04-20 23:42:38.895537632 +0200
@@ -596,7 +596,7 @@ asmlinkage long sys_setregid(gid_t rgid,
 	}
 	if (new_egid != old_egid)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		wmb();
 	}
 	if (rgid != (gid_t) -1 ||
@@ -631,7 +631,7 @@ asmlinkage long sys_setgid(gid_t gid)
 	{
 		if(old_egid != gid)
 		{
-			current->mm->dumpable=0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->gid = current->egid = current->sgid = current->fsgid = gid;
@@ -640,7 +640,7 @@ asmlinkage long sys_setgid(gid_t gid)
 	{
 		if(old_egid != gid)
 		{
-			current->mm->dumpable=0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->egid = current->fsgid = gid;
@@ -672,7 +672,7 @@ static int set_user(uid_t new_ruid, int 
 
 	if(dumpclear)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		wmb();
 	}
 	current->uid = new_ruid;
@@ -731,7 +731,7 @@ asmlinkage long sys_setreuid(uid_t ruid,
 
 	if (new_euid != old_euid)
 	{
-		current->mm->dumpable=0;
+		current->mm->dumpable = suid_dumpable;
 		wmb();
 	}
 	current->fsuid = current->euid = new_euid;
@@ -783,7 +783,7 @@ asmlinkage long sys_setuid(uid_t uid)
 
 	if (old_euid != uid)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		wmb();
 	}
 	current->fsuid = current->euid = uid;
@@ -830,7 +830,7 @@ asmlinkage long sys_setresuid(uid_t ruid
 	if (euid != (uid_t) -1) {
 		if (euid != current->euid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->euid = euid;
@@ -882,7 +882,7 @@ asmlinkage long sys_setresgid(gid_t rgid
 	if (egid != (gid_t) -1) {
 		if (egid != current->egid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->egid = egid;
@@ -932,7 +932,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
 	{
 		if (uid != old_fsuid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->fsuid = uid;
@@ -964,7 +964,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
 	{
 		if (gid != old_fsgid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			wmb();
 		}
 		current->fsgid = gid;
@@ -1659,7 +1659,7 @@ asmlinkage long sys_prctl(int option, un
 				error = 1;
 			break;
 		case PR_SET_DUMPABLE:
-			if (arg2 != 0 && arg2 != 1) {
+			if (arg2 < 0 || arg2 > 2) {
 				error = -EINVAL;
 				break;
 			}
Index: linux-2.6.5/kernel/sysctl.c
===================================================================
--- linux-2.6.5.orig/kernel/sysctl.c	2005-04-20 23:19:23.892668768 +0200
+++ linux-2.6.5/kernel/sysctl.c	2005-04-20 23:42:38.900536883 +0200
@@ -69,6 +69,7 @@ extern int sysctl_overcommit_ratio;
 extern int max_threads;
 extern int sysrq_enabled;
 extern int core_uses_pid;
+extern int suid_dumpable;
 extern char core_pattern[];
 extern int cad_pid;
 extern int pid_max;
@@ -719,6 +720,14 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
+	{
+		.ctl_name	= KERN_SETUID_DUMPABLE,
+		.procname	= "suid_dumpable",
+		.data		= &suid_dumpable,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
Index: linux-2.6.5/security/commoncap.c
===================================================================
--- linux-2.6.5.orig/security/commoncap.c	2005-04-20 23:19:06.485799323 +0200
+++ linux-2.6.5/security/commoncap.c	2005-04-20 23:45:37.579386822 +0200
@@ -133,7 +133,7 @@ void cap_bprm_compute_creds (struct linu
 
 	task_lock(current);
 	if (!cap_issubset (new_permitted, current->cap_permitted)) {
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 
 		if (must_not_trace_exec (current)
 		    || atomic_read (&current->fs->count) > 1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.linux-ha.org/pipermail/linux-ha/attachments/20050708/1d45a64d/attachment.pgp>


More information about the Linux-HA mailing list