5176669 2000-06-08 19:28 /197 rader/ Postmaster
Mottagare: Bugtraq (import) <11204>
Ärende: Sendmail 8.10.2, Linux 2.4.0 - capabilities
------------------------------------------------------------
Approved-By: aleph1@SECURITYFOCUS.COM
Delivered-To: bugtraq@lists.securityfocus.com
Delivered-To: bugtraq@securityfocus.com
X-URL: http://black-ice.cc.vt.edu/~valdis/
X-Face-Viewer: See ftp://cs.indiana.edu/pub/faces/index.html to decode picture
X-Face: 34C9$Ewd2zeX+\!i1BA\j{ex+$/V'JBG#;3_noWWYPa"|,I#`R"{n@w>#:{)FXyiAS7(8t
^*w5O*!8O9YTe[r{e%7(yVRb|qxsRYw`7J!`AM}m_SHaj}f8eb@d^L>BrX7iO[<!v4-0bVIpaxF#-
%9#a9h6JXI|T|8o6t\V?kGl]Q!1V]GtNliUtz:3},0"hkPeBuu%E,j(:\iOX-P,t7lRR#
Mime-Version: 1.0
Content-Type: multipart/mixed ; boundary="==_Exmh_13432841100"
Message-ID: <200006081628.e58GSiL29316@black-ice.cc.vt.edu>
Date: Thu, 8 Jun 2000 12:28:44 -0400
Reply-To: Valdis.Kletnieks@VT.EDU
Sender: Bugtraq List <BUGTRAQ@SECURITYFOCUS.COM>
From: Valdis Kletnieks <Valdis.Kletnieks@VT.EDU>
X-To: sendmail-bugs@sendmail.org, sendmail-security@sendmail.org
torvalds@transmeta.com, alan@redhat.com
To: BUGTRAQ@SECURITYFOCUS.COM
This is a multipart MIME message.
--==_Exmh_13432841100
Content-Type: text/plain; charset=us-ascii
The Linux 2.4.0-test1 kernel has the problem as well, as do (probably)
some of the 2.3 kernels. Just a heads-up. Yes, I know they're development.
Patch for 2.4.0-test1 attached, lightly tested. Code forward-ported
from the 2.2.16 patch. My machine still boots. ;)
My first shot at Linux kernel hacking - were there any other tweaks to
close this hole? ;)
--
Valdis Kletnieks
Operating Systems Analyst
Virginia Tech
--==_Exmh_13432841100
Content-Type: text/plain ; name="2.4.0.patch"; charset=us-ascii
Content-Description: 2.4.0.patch
Content-Disposition: attachment; filename="2.4.0.patch"
--- kernel/capability.c.dist Tue Dec 7 20:09:12 1999
+++ kernel/capability.c Thu Jun 8 11:37:02 2000
@@ -8,6 +8,8 @@
#include <linux/mm.h>
#include <asm/uaccess.h>
+kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
+
/* Note: never hold tasklist_lock while spinning for this one */
spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
@@ -16,8 +18,6 @@
* capability set pointers may be NULL -- indicating that that set is
* uninteresting and/or not to be changed.
*/
-
-kernel_cap_t cap_bset = CAP_FULL_SET;
asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
{
--- include/linux/capability.h.dist Tue Jun 6 17:27:53 2000
+++ include/linux/capability.h Thu Jun 8 11:36:36 2000
@@ -4,13 +4,16 @@
* Andrew G. Morgan <morgan@transmeta.com>
* Alexander Kjeldaas <astor@guardian.no>
* with help from Aleph1, Roland Buresund and Andrew Main.
+ *
+ * See here for the libcap library ("POSIX draft" compliance):
+ *
+ * ftp://linux.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/
*/
#ifndef _LINUX_CAPABILITY_H
#define _LINUX_CAPABILITY_H
#include <linux/types.h>
/* User-level do most of the mapping between kernel and user
capabilities based on the version tag given by the kernel. The
@@ -170,8 +174,8 @@
#define CAP_IPC_OWNER 15
-/* Insert and remove kernel modules */
-
+/* Insert and remove kernel modules - modify kernel without limit */
+/* Modify cap_bset */
#define CAP_SYS_MODULE 16
/* Allow ioperm/iopl access */
@@ -294,12 +298,12 @@
#define CAP_EMPTY_SET to_cap_t(0)
#define CAP_FULL_SET to_cap_t(~0)
#define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
-#define CAP_INIT_INH_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
+#define CAP_INIT_INH_SET to_cap_t(0)
#define CAP_TO_MASK(x) (1 << (x))
#define cap_raise(c, flag) (cap_t(c) |= CAP_TO_MASK(flag))
#define cap_lower(c, flag) (cap_t(c) &= ~CAP_TO_MASK(flag))
-#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag) &
cap_bset)
+#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag))
static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b)
{
--- fs/exec.c.dist Sun May 21 14:38:47 2000
+++ fs/exec.c Thu Jun 8 11:43:18 2000
@@ -585,21 +585,18 @@
cap_clear(bprm->cap_effective);
/* To support inheritance of root-permissions and suid-root
- * executables under compatibility mode, we raise the
- * effective and inherited bitmasks of the executable file
- * (translation: we set the executable "capability dumb" and
- * set the allowed set to maximum). We don't set any forced
- * bits.
+ * executables under compatibility mode, we raise all three
+ * capability sets for the file.
*
* If only the real uid is 0, we only raise the inheritable
- * bitmask of the executable file (translation: we set the
- * allowed set to maximum and the application to "capability
- * smart").
+ * and permitted sets of the executable file.
*/
if (!issecure(SECURE_NOROOT)) {
- if (bprm->e_uid == 0 || current->uid == 0)
+ if (bprm->e_uid == 0 || current->uid == 0) {
cap_set_full(bprm->cap_inheritable);
+ cap_set_full(bprm->cap_permitted);
+ }
if (bprm->e_uid == 0)
cap_set_full(bprm->cap_effective);
}
@@ -610,10 +607,12 @@
* privilege does not go against other system constraints.
* The new Permitted set is defined below -- see (***). */
{
- kernel_cap_t working =
- cap_combine(bprm->cap_permitted,
- cap_intersect(bprm->cap_inheritable,
- current->cap_inheritable));
+ kernel_cap_t permitted, working;
+
+ permitted = cap_intersect(bprm->cap_permitted, cap_bset);
+ working = cap_intersect(bprm->cap_inheritable,
+ current->cap_inheritable);
+ working = cap_combine(permitted, working);
if (!cap_issubset(working, current->cap_permitted)) {
cap_raised = 1;
}
@@ -646,26 +645,29 @@
* The formula used for evolving capabilities is:
*
* pI' = pI
- * (***) pP' = fP | (fI & pI)
+ * (***) pP' = (fP & X) | (fI & pI)
* pE' = pP' & fE [NB. fE is 0 or ~0]
*
* I=Inheritable, P=Permitted, E=Effective // p=process, f=file
- * ' indicates post-exec().
+ * ' indicates post-exec(), and X is the global 'cap_bset'.
*/
void compute_creds(struct linux_binprm *bprm)
{
- int new_permitted = cap_t(bprm->cap_permitted) |
- (cap_t(bprm->cap_inheritable) &
- cap_t(current->cap_inheritable));
+ kernel_cap_t new_permitted, working;
+
+ new_permitted = cap_intersect(bprm->cap_permitted, cap_bset);
+ working = cap_intersect(bprm->cap_inheritable,
+ current->cap_inheritable);
+ new_permitted = cap_combine(new_permitted, working);
/* For init, we want to retain the capabilities set
* in the init_task struct. Thus we skip the usual
* capability rules */
if (current->pid != 1) {
- cap_t(current->cap_permitted) = new_permitted;
- cap_t(current->cap_effective) = new_permitted &
- cap_t(bprm->cap_effective);
+ current->cap_permitted = new_permitted;
+ current->cap_effective =
+ cap_intersect(new_permitted, bprm->cap_effective);
}
/* AUD: Audit candidate if current->cap_effective is set */
--==_Exmh_13432841100--
(5176669) ------------------------------------------(Ombruten)