File ksh93-suid_exec.dif of Package ksh

--- src/cmd/ksh93/data/msg.c
+++ src/cmd/ksh93/data/msg.c	2014-02-18 16:08:16.662492587 +0000
@@ -208,7 +208,11 @@ const char e_bash_profile[]	= "$HOME/.ba
 const char e_crondir[]		= "/var/spool/cron";
 const char e_prohibited[]	= "login setuid/setgid shells prohibited";
 #if SHOPT_SUID_EXEC
+#  ifdef THISPROG
+   const char e_suidexec[]	= THISPROG;
+#  else
    const char e_suidexec[]	= "/etc/suid_exec";
+#  endif
 #endif /* SHOPT_SUID_EXEC */
 const char hist_fname[]		= "/.sh_history";
 const char e_dot[]		= ".";
--- src/cmd/ksh93/sh/suid_exec.c
+++ src/cmd/ksh93/sh/suid_exec.c	2014-02-18 16:10:34.891601497 +0000
@@ -62,10 +62,24 @@
 #define FDVERIFY	12	/* used to validate /tmp process */
 #undef BLKSIZE 
 #define BLKSIZE		sizeof(char*)*1024
-#define THISPROG	"/etc/suid_exec"
-#define DEFSHELL	"/bin/sh"
+#ifndef THISPROG
+#  define THISPROG	"/etc/suid_exec"
+#endif
+#ifndef DEFSHELL
+#  define DEFSHELL	"/bin/sh"
+#endif
 
+#if defined(__linux__)
+static void error_exit(const char*) __attribute__ ((noreturn));
+#ifndef _lib_setregid
+#define _lib_setregid	1
+#endif
+#ifndef _lib_setreuid
+#define _lib_setreuid	1
+#endif
+#else
 static void error_exit(const char*);
+#endif
 static int in_dir(const char*, const char*);
 static int endsh(const char*);
 #ifndef _lib_setregid
@@ -76,7 +90,7 @@ static int endsh(const char*);
     static int mycopy(int, int);
     static void maketemp(char*);
 #else
-    static void setids(int,int,int);
+    static void setids(int,uid_t,gid_t);
 #endif /* _lib_setreuid */
 
 static const char version[]	= "\n@(#)$Id: suid_exec "SH_RELEASE" $\n";
@@ -221,7 +235,7 @@ int main(int argc,char *argv[])
 		if(effuid != ruserid)
 			mode |= S_ISUID;
 	}
-	else if(effuid)
+	else if(effuid != euserid)
 	{
 		if(effuid != ruserid || setuid(ruserid) < 0)
 			mode = S_ISUID;
@@ -233,13 +247,18 @@ int main(int argc,char *argv[])
 exec:
 #endif /* _lib_setreuid */
 	/* only use SHELL if file is in trusted directory and ends in sh */
+#ifndef __linux__
 	shell = getenv("SHELL");
 	if(shell == 0 || !endsh(shell) || (
 		!in_dir("/bin",shell) &&
 		!in_dir("/usr/bin",shell) &&
-		!in_dir("/usr/lbin",shell) &&
 		!in_dir("/usr/local/bin",shell)))
 			shell = DEFSHELL;
+#else
+	shell = DEFSHELL;
+	if(!endsh(shell))
+		error_exit(badexec);
+#endif
 	argv[0] = command;
 	argv[1] = (char*)devfd;
 	execv(shell,argv);
@@ -249,7 +268,7 @@ exec:
 /*
  * return true of shell ends in sh of ksh
  */
-
+#ifndef __linux__
 static int endsh(register const char *shell)
 {
 	while(*shell)
@@ -262,7 +281,20 @@ static int endsh(register const char *sh
 		return(1);
 	return(0);
 }
-
+#else
+static int endsh(const char *shell)
+{
+	char * shx;
+	while ((shx = getusershell())) {
+		if (strcmp(shx, shell) == 0) {
+			endusershell();
+			return(1);
+		}
+	}
+	endusershell();
+	return(0);
+}
+#endif
 
 /*
  * return true of shell is in <dir> directory
@@ -345,16 +377,31 @@ int eaccess(register const char *name, r
 #endif
 
 #ifdef _lib_setreuid
-static void setids(int mode,int owner,int group)
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+static void setids(int mode,uid_t owner,gid_t group)
 {
 	if(mode & S_ISGID)
-		setregid(rgroupid,group);
+	{
+		struct passwd *pwd;
+
+		if (setregid(rgroupid,group) < 0)
+			error_exit(badexec);
+
+		if (((pwd = getpwuid(owner)) == (struct passwd*)0) || !(pwd->pw_name))
+			error_exit(badexec);
+
+		if (initgroups (pwd->pw_name, group))
+			error_exit(badexec);
+	}
 
 	/* set effective uid even if S_ISUID is not set.  This is because
 	 * we are *really* executing EUID root at this point.  Even if S_ISUID
 	 * is not set, the value for owner that is passsed should be correct.
 	 */
-	setreuid(ruserid,owner);
+	if (setreuid(ruserid,owner) < 0)
+		error_exit(badexec);
 }
 
 #else