Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Sep 2001 14:35:10 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        security@FreeBSD.org
Subject:   at(1) sugid fixes
Message-ID:  <20010903143510.D49997@sunbay.com>

next in thread | raw e-mail | index | archive | help

--Kj7319i9nmIyA2yE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi!

The attached patch fixes at(1) macros that manipulate user
and group IDs of the proccess so that they don't change the
real user and group IDs of the process, and instead use the
saved user and group IDs feature.

The setre[ug]id() calls are still used with the REDUCE_PERM
macro (with the r[ug]id arguments of -1) so that the call
changes the saved user/group ID of the process to that
specified.

That is to say, if the process was initially run ``setuid
root'', the call to ``REDUCE_PERM(1, ...)'' changes the
process's saved-user-ID to that of the user "daemon", and
the process then becomes ``setuid daemon'' (with effective
privileges temporarily relinquished to the real privileges).

Also, the panic() and perr() functions had insufficient
privileges to delete the problematic file under /var/at.

Comments/reviews are welcome.


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

--Kj7319i9nmIyA2yE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=p

Index: panic.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/at/panic.c,v
retrieving revision 1.10
diff -u -p -r1.10 panic.c
--- panic.c	1999/12/05 19:57:14	1.10
+++ panic.c	2001/09/03 11:21:00
@@ -39,6 +39,7 @@ static const char rcsid[] =
 /* Local headers */
 
 #include "panic.h"
+#include "privs.h"
 #include "at.h"
 
 /* External variables */
@@ -50,8 +51,11 @@ panic(char *a)
 {
 /* Something fatal has happened, print error message and exit.
  */
-	if (fcreated)
+	if (fcreated) {
+		PRIV_START
 		unlink(atfile);
+		PRIV_END
+	}
 
 	errx(EXIT_FAILURE, "%s", a);
 }
@@ -63,8 +67,11 @@ perr(char *a)
  */
 	int serrno = errno;
 
-	if (fcreated)
+	if (fcreated) {
+		PRIV_START
 		unlink(atfile);
+		PRIV_END
+	}
 
 	errno = serrno;
 	err(EXIT_FAILURE, "%s", a);
Index: privs.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/at/privs.h,v
retrieving revision 1.7
diff -u -p -r1.7 privs.h
--- privs.h	1999/12/05 19:57:14	1.7
+++ privs.h	2001/09/03 11:21:00
@@ -28,17 +28,11 @@
 #ifndef _PRIVS_H
 #define _PRIVS_H
 
-#ifndef _USE_BSD
-#define _USE_BSD 1
 #include <unistd.h>
-#undef _USE_BSD
-#else
-#include <unistd.h>
-#endif
 
 /* Relinquish privileges temporarily for a setuid or setgid program
- * with the option of getting them back later.  This is done by swapping
- * the real and effective userid BSD style.  Call RELINQUISH_PRIVS once
+ * with the option of getting them back later.  This is done by
+ * utilizing POSIX saved user and group IDs.  Call RELINQUISH_PRIVS once
  * at the beginning of the main program.  This will cause all operations
  * to be executed with the real userid.  When you need the privileges
  * of the setuid/setgid invocation, call PRIV_START; when you no longer
@@ -76,38 +70,39 @@ extern
 gid_t real_gid, effective_gid;
 
 #define RELINQUISH_PRIVS { \
-			      real_uid = getuid(); \
-			      effective_uid = geteuid(); \
-			      real_gid = getgid(); \
-			      effective_gid = getegid(); \
-			      setreuid(effective_uid, real_uid); \
-			      setregid(effective_gid, real_gid); \
-		          }
-
-#define RELINQUISH_PRIVS_ROOT(a,b) { \
-			      real_uid = (a); \
-			      effective_uid = geteuid(); \
-			      real_gid = (b); \
-			      effective_gid = getegid(); \
-			      setregid(effective_gid, real_gid); \
-			      setreuid(effective_uid, real_uid); \
-		          }
-
-#define PRIV_START {\
-		    setreuid(real_uid, effective_uid); \
-		    setregid(real_gid, effective_gid);
-
-#define PRIV_END \
-		    setregid(effective_gid, real_gid); \
-		    setreuid(effective_uid, real_uid); \
-		    }
-
-#define REDUCE_PRIV(a,b) {\
-			setreuid(real_uid, effective_uid); \
-			setregid(real_gid, effective_gid); \
-			effective_uid = (a); \
-			effective_gid = (b); \
-			setregid(effective_gid, real_gid); \
-			setreuid(effective_uid, real_uid); \
-		    }
+	real_uid = getuid(); \
+	effective_uid = geteuid(); \
+	real_gid = getgid(); \
+	effective_gid = getegid(); \
+	seteuid(real_uid); \
+	setegid(real_gid); \
+}
+
+#define RELINQUISH_PRIVS_ROOT(a, b) { \
+	real_uid = (a); \
+	effective_uid = geteuid(); \
+	real_gid = (b); \
+	effective_gid = getegid(); \
+	setegid(real_gid); \
+	seteuid(real_uid); \
+}
+
+#define PRIV_START { \
+	seteuid(effective_uid); \
+	setegid(effective_gid); \
+}
+
+#define PRIV_END { \
+	setegid(real_gid); \
+	seteuid(real_uid); \
+}
+
+#define REDUCE_PRIV(a, b) { \
+	PRIV_START \
+	effective_uid = (a); \
+	effective_gid = (b); \
+	setreuid((uid_t)-1, effective_uid); \
+	setregid((gid_t)-1, effective_gid); \
+	PRIV_END \
+}
 #endif

--Kj7319i9nmIyA2yE--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010903143510.D49997>