[Users] Solar Designer Audit 2005

Sergey Bronnikov sergeyb at openvz.org
Mon Oct 12 02:42:42 PDT 2015


On 09:04 Tue 12 May , apoc at keemail.me wrote:
> Hello!I'm interested in the security audit performed by Solar Designer in 
> 2005, which is mentioned in the "Security" section of the openvz website.
> Is there a reason why it's still not publicly available?
> greetings apoc

Alexander found a report which was done for OpenVZ in 2005.
I have attached it.

> _______________________________________________
> Users mailing list
> Users at openvz.org
> https://lists.openvz.org/mailman/listinfo/users
-------------- next part --------------
>From solar at openwall.com Thu Dec  1 03:53:19 2005
Date: Thu, 1 Dec 2005 03:53:19 +0300
From: Solar Designer <solar at openwall.com>
To: security at openvz.org
Subject: report for OpenVZ security audit phase 1
Message-ID: <20051201005319.GA19353 at openwall.com>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="PEIAKu/WMn1b1Hv9"
Content-Disposition: inline
User-Agent: Mutt/1.4.2.1i
Status: RO
Content-Length: 52693
Lines: 903


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

Kirill et al.,

The report is attached as a text/plain file (such that you can easily
comment on it in a follow-up e-mail if needed) and also as a part of the
bigger tarball (which includes other relevant files as well).

Thanks,

-- 
Alexander

--PEIAKu/WMn1b1Hv9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=report-1

	OpenVZ security audit, phase 1, Sep 15 through Nov 30, 2005.


	High-level subsystems/features covered in the audit.

The following components were included in the audit:

1. The kernel:

OpenVZ kernel patch (initially patch-022stab034-core, later
patch-022stab038-core, patch-022stab045-combined, and finally
patch-022stab050-combined).  Most of the analysis was performed on
patch-022stab038-core.

The entire OpenVZ kernel (that is, Linux 2.6.8 with the OpenVZ patch
applied).  Only a small portion of the kernel sources was actually
reviewed and/or stress-tested.  This includes code paths specifically
affected by changes made in OpenVZ as well as kernel subsystems and
their properties that are especially important for correct analysis of
OpenVZ-introduced code and changes.

Priority was given to features enabled with the default OpenVZ kernel
configurations.

The kernel was _not_ checked for any non-OVZ-specific vulnerabilities
that are fixed upstream.

2. vzctl (initially vzctl-2.7.0-21, later vzctl-2.7.0-24).

3. vzpkg (vzpkg-2.7.0-17) and vzrpm (vzrpm44-4.4.1-22.5).

4. vzquota (vzquota-2.7.0-7).

Only partial reviews of vz* utilities were performed, please see below.


	Portions of code and vulnerability classes that have been covered.

The following portions of code have been reviewed and/or tested and the
vulnerability classes checked for, arranged by OpenVZ component:

1. The kernel:

1.1. The entire OpenVZ kernel source tree has been checked for:

1.1.1. Actions allowed specifically with any one of a process' UIDs
(uid, euid, fsuid) being zero.  This is likely Linux pre-2.2 heritage
which is not valid under the capability model and would potentially
result in very practical vulnerabilities with the OpenVZ security model.

Automated checking was used initially ("grep" with many regular
expressions aimed to catch most common ways to check UIDs against zero),
followed by manual review of pieces of code containing the lines with
matches.

A handful of problematic UID checks like this was actually identified
(added to "checklist" and commented on in "remarks-038-10").  These are
located in facilities that are unlikely to be compiled into OpenVZ
kernels or are otherwise not particularly relevant to OpenVZ.  They need
to be reported upstream.

The LSMs located under security/, except for security/commoncap.c, have
been specifically excluded from the audit.  Some are known to ruin the
OpenVZ security model.  The recommendation is to document this.

1.1.2. Actions allowed specifically with capabilities included in
vzctl's CAPDEFAULTMASK.

A number of problems were discovered, including upstream bugs with and
without OVZ specifics, actions which shouldn't have been allowed for
VPSes or which need virtualization, and possibilities for uncontrolled
consumption of kernel resources.  All of these have been appropriately
marked in the "checklist" and some also in "remarks-038-10".

CAP_NET_RAW involved a significant amount of testing for other VPSes'
network traffic sniffing with different socket types and for raw packet
injections with spoofed source addresses.  It passed the tests.

Only a small number of instances of capability checks haven't been
reviewed for real (but have been added to the "checklist").  These have
been determined to not be particularly relevant and/or to be relatively
hard (time-consuming) to review and validate.

1.2. Code paths related to dropping of CAP_SETVEID on VPS creation and
entry.  Passed review and testing.

1.3. Definition and uses of cap_set_full().  Uses of CAP_FULL_SET and
CAP_INIT_EFF_SET.  Passed review.

1.4. Potential missing restrictions for VPS root vs. host root (lack of
virtualization) and unsafe code in:

1.4.1. Syscalls available to VPS root but not to users, as identified by
"sysfuzzer" (23 syscalls).  One OVZ vulnerability and one
non-OVZ-specific upstream problem were identified.

1.4.2. Syscalls which were explicitly excluded from "sysfuzzer" (reboot,
vhangup).  Passed review.

1.4.3. Syscalls which might also be available to VPS root but not to
users, but which could have been missed by "sysfuzzer".  The entire list
of syscalls supported on i386 was reviewed manually and potentially
relevant ones (53 syscalls) were selected for review and/or testing.  A
couple of problems were identified.

The problems identified with syscall reviews matched those identified
with the review on capabilities described above.

Complete lists of syscalls checked (reviewed and/or tested) along with
the status for each are included in the "checklist".

1.4.4. ioctls available to VPS root but not to users.  All devices major
and minor numbers (for majors up to 1023) for both character and block
devices were brute-forced and open()able ones listed.  No unexpected or
unintended ones were identified.  A bug allowing for VPS root initiated
node crashes was triggered (and has been fixed before revision 050).
Non-OVZ-specific issues with /dev/*random were raised on the mailing
list.

1.4.5. sysctls.  Passed testing for proper virtualization.

1.5. All of the OVZ-introduced code has been checked for certain generic
vulnerability classes, as described below.  However, it has not been
manually reviewed in its entirety.

1.5.1. Uses of __{get,put}_user() and __copy_{to,from}_user() where
"non-underscored" versions of these macros/functions are required.  No
erroneous uses found.

1.5.2. All identified syscall wrappers were checked for possible race
conditions which could result from copying of arguments passed by
reference from the user-space twice.  No such race conditions were
found.  The list of functions identified and checked is available in the
"checklist".

However, other race conditions were identified in ip_tables.c:
do_add_counters() (as well as in other instances of this code) and in
do_env_enter().

1.5.3. All *[kv]malloc() calls in patch context have been checked for
possible integer overflows when calculating the allocation sizes.  Such
integer overflows were actually discovered in ip_tables.c (and in other
instances of this code).

1.5.4. All *[kv]malloc() calls in patch context have been checked for
allocations of user-controlled amounts of memory with no sanity limits.
The only ones identified are beancounted.

1.6. The classical chroot break (see "breakout.c") was attempted.
Unexpectedly, it resulted in an Oops.  The bug has since been fixed and
"breakout.c" fails as it should now.

1.7. Both code reviews and testing was done on possibilities to access
another VE's processes by PID, using PTRACE_ATTACH, kill(2), and
setpriority(2).  The results are consistent: such attempts fail from
within a VPS, whereas non-root users on the host system are permitted to
access in-VPS processes which happen to run under the same UID.

1.8. It was tested whether host filesystem mount flags (noexec, nosuid,
nodev) have any effect on VPSes using simfs.  The answer is "no", they
don't.  This may be documented to avoid any confusion and to "legalize"
the use of "noexec" for some limited protection of the host system from
accidental execution of files from VPSes.

1.9. An attempt was made to identify resources that are not properly
beancounted and not limited for individual VPSes.  tmpfs allocations
passed the test.  Loopback mounts also passed both code review and
testing for the simple reason that they're not available in VPSes.
However, route tables, network interfaces (aliases), bind mounts, and
tmpfs mounts have been determined to not be properly beancounted or
limited.  Additionally, the queues_count variable in ipc/mqueue.c is not
virtualized, potentially allowing to DoS the functionality for non-root
users in all VPSes and on the host system.

1.10. Some other OVZ-introduced code and some other changes applied with
the OVZ patch have been reviewed manually.  Some of these are listed in
the "checklist".

2. vzctl:

2.1. The VPS entry code paths were reviewed, leading to the discovery of
a race condition in the kernel's do_env_enter().

2.2. Testing and review of "strace" logs revealed that only the first 16
fd's were being closed on VPS entry.  This needs to be corrected.  Also,
the fd's are being closed _after_ the ioctl call, which is not great,
although the risk is now mitigated by having the VPS-entering process
protected from ptrace(2).

2.3. The permissions on files and directories created by vzctl were
checked.  It was determined that vzctl.spec doesn't explicitly set
permissions on /dev/vzctl, letting them depend on umask.  This needs to
be corrected.  Additionally, it is preferable for default permissions on
/vz/private to be forced to 700 (which is not the case currently, unless
running with umask 077 which is uncommon).  The rationale for this was
discussed on the mailing list (potential fd passing).

2.4. The default capabilities list has been reviewed and it will need to
be revised as a result of the kernel reviews.

2.5. The vzctl(8) manual page has been reviewed for its description of
the --capability option.  It has been determined that a warning should
be added stating that enabling non-default capabilities may completely
break the OpenVZ security model.

3. vzpkg and vzrpm:

3.1. Initially, vzpkg was determined to be using host's rpm and yum on
VPSes.  This was obviously insecure.

3.2. vzrpm would properly switch to VE context when executing scripts,
however a brief review of source code of RPM revealed many other vectors
for attack by a malicious VPS.

Because of these flaws, no further reviews on these utilities were done.

4. vzquota:

4.1. quotacheck.c was reviewed in its entirety.  It was determined to be
safe to use on stopped VPSes, but unsafe on running ones (three distinct
race conditions were identified).

4.2. It was checked that quota_io.c: open_quota_file() properly sets
safe permissions on the file and there are no other O_CREATs or creat()
calls in vzquota.

The rest of vzquota was determined to not be thoroughly reviewed due to
serious security issues being unlikely there.


	OpenVZ-specific security issues found.

These are mostly in "checklist" order:

1. The kernel:

1.1. Issues "enabled" with capabilities granted to VPS root:

1.1.1. CAP_NET_RAW enables SO_BINDTODEVICE.  The code for SO_BINDTODEVICE
does not process non-NUL-terminated devname[] strings correctly,
potentially allowing for leaks of information off the kernel stack
(leftovers from previous activity), at a rate of 1 bit per 128 syscalls
or better.  The code needs to be corrected.

1.1.2. CAP_SYS_PTRACE: arch/ia64/kernel/perfmon.c and
arch/ia64/kernel/ptrace.c were not virtualized.  This has since been
fixed.

1.1.3. CAP_SYS_PACCT: is not virtualized at all, should be dropped from
the default capability set.

1.1.4. CAP_SYS_NICE: enables SCHED_FIFO and SCHED_RR.  It has since been
determined to disallow those for VPSes.

1.1.5. CAP_SYS_RESOURCE used to allow for setublimit() and ubstat() to be
invoked from within VPS.  This has since been fixed.

1.1.6. CAP_VE_SYS_ADMIN and CAP_VE_NET_ADMIN enable several things which
needed to be fixed: the code in ip_tables.c with its security issues
(already fixed), mount (no limit on number of mounts in a VPS, not yet
fixed), net/ipv4/devinet.c (no limit on number of interfaces, not yet
fixed), net/ipv4/fib_frontend.c (no limit on number of routes, not yet
fixed).

1.2. Oops / node crash bug in alloc_ve_tty_driver().  Already fixed.

1.3. Assorted issues in ip_tables.c (integer overflows when calculating
allocation sizes, race conditions).  These are already fixed.  Similar
bugs in other instances of this code are not fixed (but that code is
currently not used on OVZ).

1.4. Oops / node crash bug triggerable with the classical chroot break.
Already fixed.

1.5. Host system non-root to VPS attacks with matching UIDs.  Subtle host
non-root + VPS root => host root attack with fd passing.  The latter may
be worked around with hardened permissions on /vz/private (700).  None
of this is currently fixed.

1.6. do_env_enter() race condition with (re)setting capabilities too late.
Fixed.

1.7. route tables, network interfaces (aliases), and mounts are not
properly beancounted or limited, allowing for DoS attacks on the host
node.  route table flood appears to be the most effective, leading to
the system running out of physical memory within minutes.

1.8. The queues_count variable in ipc/mqueue.c is not virtualized,
potentially allowing to DoS the functionality for non-root users in all
VPSes and on the host system.

2. vzctl:

2.1. Only the first 16 fd's are being closed on VPS entry.  This needs
to be corrected.  Ideally, all but fd 0-2 and the fd needed for the
ioctl should be closed before the ioctl.

2.2. vzctl.spec doesn't explicitly set permissions on /dev/vzctl,
letting them depend on umask.  This needs to be corrected.
Additionally, it is preferable for default permissions on /vz/private to
be forced to 700.

2.3. The default capabilities list should be revised.  CAP_SYS_PACCT
should be dropped.  If possible, CAP_SYS_TTY_CONFIG should also be
dropped.

2.4. A warning should be added to the vzctl(8) manual page stating that
enabling non-default capabilities may completely break the OpenVZ
security model.  Maybe vzctl itself should print a warning, too, when
requested to set known-unsafe capabilities.

3. vzpkg and vzrpm:

3.1. Initially, vzpkg was determined to be using host's rpm and yum on
VPSes.  This was obviously insecure.

3.2. vzrpm would properly switch to VE context when executing scripts,
however a brief review of source code of RPM revealed many other vectors
for attack by a malicious VPS, including via NSS modules, libraries'
configuration files, malicious/changing Berkeley databases (disobeying
any locking conventions), and symlink races exploiting the fact that RPM
would keep its current directory outside of the chroot point.

It has been agreed that vzrpm should be ditched and the packages to
install/update should be introduced into the VPS instead, to be
installed with an in-VPS instance of RPM.

4. vzquota's vzdqcheck, "vzquota on ... -p ...", and
"vzquota init ... -p ..." have been determined to be unsafe to use on
running VPSes (perhaps they shouldn't be used like that anyway).
It would be preferable to add a check making them refuse to work like
that.  The difficulty here appears to be that vzdqcheck and vzquota are
only supplied directory paths and not veid's.  Maybe that should be
re-worked, to have all utilities accept veid's and translate them to
paths using a common library?

Alternatively, maybe the race conditions should be resolved (to the
extent possible without further changes to the kernel).  The easiest
initial workaround could be to change the open flags in get_inode_size()
to (O_RDONLY | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW).  This won't help
against mknod()s of rewinding tape device files, but not that many
systems have tape drives.


	Portions of code and potential issues yet to be checked for.

Essentially all lines on "checklist" that do not start with a plus (item
completed) or minus (determined to not be done) may be worked on.  The
most important of these are, described in plain English:

1. The OVZ-introduced code should be reviewed in its entirety.  As it
has been described above, so far only portions of the code have been
thoroughly reviewed, whereas the rest has only been checked for certain
classes of vulnerabilities, -- and the primary focus was on higher risk
issues (with risk probability taken into account) with OpenVZ kernel at
large.  Now that all capability uses, syscalls, etc. have been checked
(with very few exceptions) would be a good time to proceed with further
reviews of all of the OVZ-introduced code.

2. We should double-check that OpenVZ contains all relevant upstream
security fixes applied after Linux 2.6.8.1.  Any missing fixes should be
back-ported and applied.  Alternatively, OpenVZ should be updated to a
newer base kernel version (ideally, this should be done regularly).

3. vzctl should be reviewed in its entirety.

4. Once fixes for the issues identified so far are available, they will
need to be peer-reviewed.  This applies to both kernel and user-space
code fixes.

5. Once vzpkg implements an alternate approach that is not fundamentally
flawed, vzpkg will also need to be reviewed in its entirety.

6. Security of the infrastructure around OpenVZ will need to be
considered.  Is all of the code being distributed signed?  With what
key?  Is the private key secure?  Where people are supposed to obtain
the public key and how they verify its authenticity?  Are development
systems secure?  Are distribution websites, mirrors, etc. secure?  What
process is there to announce security updates?  And so on.


	Recommendations for "hardening" OpenVZ security.

1. Kirill's proposed dentry-based "area checks" should be fully
implemented, both as a hardening measure against "escaped" VPSes and as
a policy enforcement and safety measure for tools used off the host
system.  In particular, it could be used to make host-initiated backups
and quotachecks safe (or at least safer than they are now).

2. Certain risky/irrelevant functionality that Linux normally provides
could be disabled for VPSes.  vm86() and vm86old() syscalls would be an
example.

3. The most reliable way to deal with attacks based on matching UIDs is
to simply not have those, but rather translate full 32-bit unique
UIDs/GIDs to VPS-specific ones on kernel interfaces.  This has been
briefly discussed on the mailing list.  The biggest disadvantage that
was mentioned is that it would make it harder to migrate VPSes across
nodes.

It was suggested that matching UIDs/GIDs could continue to be used in
different VPSes, but they would be different from those the host system
would use.  In order to ensure cross-VPS security even if an attacker
would manage to escape from a VPS' chroot jail, permissions on
/vz/private would need to be set to 700 (with host root as the owner),
which is being recommended above for other reasons anyway.  Additionally,
the meaning of certain capabilities (CAP_DAC_OVERRIDE, etc.) would need
to be "virtualized" when in VE context.  That is, the DAC override would
apply only to files whose owner UIDs fall within the VPS' range, etc.

Unfortunately, with all these considerations, this does appear to be not
so trivial to implement.  So this is more of an idea for further
discussion rather than a final recommendation.

4. It may be possible to replace the temporary exec_env and exec_ub
switches on IRQs, etc. with a safer concept.  The issue has just been
raised on the mailing list and not yet discussed, so it is too early to
position it as a "recommendation".

--PEIAKu/WMn1b1Hv9
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="deliverable-1.tar.gz"
Content-Transfer-Encoding: base64

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

--PEIAKu/WMn1b1Hv9--

>From solar at openwall.com Mon Jan 16 22:41:07 2006
Date: Mon, 16 Jan 2006 22:41:07 +0300
From: Solar Designer <solar at openwall.com>
To: Kirill Korotaev <dev at sw.ru>
Cc: Kir Kolyshkin <kir at openvz.org>
Subject: Re: review announce
Message-ID: <20060116194107.GA3672 at openwall.com>
References: <43CB90A0.6090303 at sw.ru>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <43CB90A0.6090303 at sw.ru>
User-Agent: Mutt/1.4.2.1i
Status: RO
Content-Length: 2360
Lines: 59

Hi Kirill and Kir,

On Mon, Jan 16, 2006 at 03:25:04PM +0300, Kirill Korotaev wrote:
> Hope you are well.

Yeah, just extremely busy and tired... as usual.  I hope all is well
with you, too.

> We plan to make OVZ security review announce, say in 2 weeks.
> How are you with it? Your name will be mentioned, maybe you want us to 
> provide some additional information about this? Kir will send a draft of 
> the announce later.
> 
> Some of the problems you found with huge amount of mounts/interfaces and 
> vzrpm are still not fixed though. And this is mostly the reason why I 
> ask your opinion. I will handle these issues after vz3.0 release which 
> should happen soon.

I am concerned about your not fixing vzrpm.  Yes, please do give me an
opportunity to review a draft of the announcement before you send it
out.  I imagine, you would not want to hint to possible security issues
with vzrpm in the announcement, but at the same time I wouldn't want
responsibility for having "missed" those fundamental issues when they
become public a bit later (as you release a fixed version or otherwise).

I am not so concerned about the DoS issues, although I think you could
have applied workarounds for them easily (just hard-code some sane
limits that would not be reached in normal VPS operation), -- and that
would do for now.

> BTW, we are trying to push now OpenVZ to SUSE kernel, and your name is 
> also mentioned there as an external code reviewer.

OK.  The same concern regarding vzrpm applies here, if vzrpm is
documented as covered by the review.

Maybe the security review announcement could list components covered by
the review: ovzkernel, vzctl, vzquota.  Just omit vzrpm and vzpkg.
Would that work for you?

What mainstream kernel version does SUSE use?  If it's different from
2.6.8, then some of the checks on OVZ that I've performed do not apply.

P.S. The news item on vzctl 2.7.0-25 includes:

* Security: do preload libnss on enter action

This got me curious.  I don't think there was a security issue (since
vzctl enter is meant to ultimately execute code from within the VPS and
AFAIR it didn't perform any NSS calls after the chroot() but before
entering VPS context) and I'm also not sure how you're preloading NSS
(I'm not aware of a reliable way to do it).

But this change is good as a hardening measure.

Thanks,

-- 
Alexander

>From solar at openwall.com Wed Jan 18 20:34:12 2006
Date: Wed, 18 Jan 2006 20:34:12 +0300
From: Solar Designer <solar at openwall.com>
To: Linus Torvalds <torvalds at osdl.org>, Andrew Morton <akpm at osdl.org>,
	security at kernel.org, davem at davemloft.net,
	Rusty Russell <rusty at rustcorp.com.au>,
	Stanislav Protassov <st at sw.ru>, Kirill Korotaev <dev at sw.ru>
Subject: [AUDIT] assorted comments on Linux 2.6
Message-ID: <20060118173412.GA13580 at openwall.com>
References: <43CE507B.1090702 at sw.ru>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="n8g4imXOkfNTN/H1"
Content-Disposition: inline
In-Reply-To: <43CE507B.1090702 at sw.ru>
User-Agent: Mutt/1.4.2.1i
Status: RO
Content-Length: 11510
Lines: 333


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

Linus et al.,

This is a follow-up to the two issues that Kirill has provided patches
for today.  Basically, the OpenVZ security audit that I've performed
resulted in the discovery of a few (yes, only a few) security-relevant
bugs in the kernel itself.  Some of those do not affect the security of
typical systems because certain capabilities are required to trigger the
bugs, however they do affect virtualization solutions on top of Linux
which make extensive use of capabilities.  The netfilter issues are an
example of this.

There are, however, issues which may be relevant to typical installs as
well.  Attached to this message is a non-patch commenting on some of my
findings.  I've removed from it the issues that Kirill has already
reported (and provided real patches for).

In this non-patch, I am using the following keywords:

AUDIT-UN - Upstream, Non-security (but this actually has security impact
on patched kernels where the functionality is made available to users
that are not fully trusted, and OpenVZ is not the only project affected)

AUDIT-UL - Upstream, Low severity

AUDIT-UM - Upstream, Medium severity

No "Upstream, High severity" issues were discovered.  (But the primary
focus was on OpenVZ specifics rather than on the mainstream kernel.)

Obviously, I am not bothering you with any "non-upstream" issues.

I am sorry that I currently do not have the time to properly handle
this, provide real patches, etc.  I am providing this in hope that it
will be useful, but with no expectations.

Thanks,

-- 
/sd

--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="linux-2.6.15.1-audit-comments.notapatch"

diff -rpU 10 linux-2.6.15.1.orig/drivers/acpi/asus_acpi.c linux-2.6.15.1/drivers/acpi/asus_acpi.c
--- linux-2.6.15.1.orig/drivers/acpi/asus_acpi.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/drivers/acpi/asus_acpi.c	Wed Jan 18 19:56:56 2006
@@ -840,20 +840,21 @@ static int __init asus_hotk_add_fs(struc
 {
 	struct proc_dir_entry *proc;
 	mode_t mode;
 
 	/*
 	 * If parameter uid or gid is not changed, keep the default setting for
 	 * our proc entries (-rw-rw-rw-) else, it means we care about security,
 	 * and then set to -rw-rw----
 	 */
 
+/* AUDIT-UM: so much for "safe defaults"... */
 	if ((asus_uid == 0) && (asus_gid == 0)) {
 		mode = S_IFREG | S_IRUGO | S_IWUGO;
 	} else {
 		mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
 	}
 
 	acpi_device_dir(device) = asus_proc_dir;
 	if (!acpi_device_dir(device))
 		return -ENODEV;
 
diff -rpU 10 linux-2.6.15.1.orig/drivers/char/agp/frontend.c linux-2.6.15.1/drivers/char/agp/frontend.c
--- linux-2.6.15.1.orig/drivers/char/agp/frontend.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/drivers/char/agp/frontend.c	Wed Jan 18 19:56:56 2006
@@ -703,20 +703,21 @@ static int agp_open(struct inode *inode,
 	if (minor != AGPGART_MINOR)
 		goto err_out;
 
 	priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
 	if (priv == NULL)
 		goto err_out_nomem;
 
 	set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
 	priv->my_pid = current->pid;
 
+/* AUDIT-UL: should check a capability */
 	if ((current->uid == 0) || (current->suid == 0)) {
 		/* Root priv, can be controller */
 		set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);
 	}
 	client = agp_find_client_by_pid(current->pid);
 
 	if (client != NULL) {
 		set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
 		set_bit(AGP_FF_IS_VALID, &priv->access_flags);
 	}
diff -rpU 10 linux-2.6.15.1.orig/drivers/net/wan/sbni.c linux-2.6.15.1/drivers/net/wan/sbni.c
--- linux-2.6.15.1.orig/drivers/net/wan/sbni.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/drivers/net/wan/sbni.c	Wed Jan 18 19:56:56 2006
@@ -1318,37 +1318,39 @@ sbni_ioctl( struct net_device  *dev,  st
 #endif
   
 	switch( cmd ) {
 	case  SIOCDEVGETINSTATS :
 		if (copy_to_user( ifr->ifr_data, &nl->in_stats,
 					sizeof(struct sbni_in_stats) ))
 			error = -EFAULT;
 		break;
 
 	case  SIOCDEVRESINSTATS :
+/* AUDIT-UL: should check a capability */
 		if( current->euid != 0 )	/* root only */
 			return  -EPERM;
 		memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
 		break;
 
 	case  SIOCDEVGHWSTATE :
 		flags.mac_addr	= *(u32 *)(dev->dev_addr + 3);
 		flags.rate	= nl->csr1.rate;
 		flags.slow_mode	= (nl->state & FL_SLOW_MODE) != 0;
 		flags.rxl	= nl->cur_rxl_index;
 		flags.fixed_rxl	= nl->delta_rxl == 0;
 
 		if (copy_to_user( ifr->ifr_data, &flags, sizeof flags ))
 			error = -EFAULT;
 		break;
 
 	case  SIOCDEVSHWSTATE :
+/* AUDIT-UL: should check a capability */
 		if( current->euid != 0 )	/* root only */
 			return  -EPERM;
 
 		spin_lock( &nl->lock );
 		flags = *(struct sbni_flags*) &ifr->ifr_ifru;
 		if( flags.fixed_rxl )
 			nl->delta_rxl = 0,
 			nl->cur_rxl_index = flags.rxl;
 		else
 			nl->delta_rxl = DEF_RXL_DELTA,
@@ -1356,35 +1358,37 @@ sbni_ioctl( struct net_device  *dev,  st
 
 		nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
 		nl->csr1.rate = flags.rate;
 		outb( *(u8 *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );
 		spin_unlock( &nl->lock );
 		break;
 
 #ifdef CONFIG_SBNI_MULTILINE
 
 	case  SIOCDEVENSLAVE :
+/* AUDIT-UL: should check a capability */
 		if( current->euid != 0 )	/* root only */
 			return  -EPERM;
 
 		if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
 			return -EFAULT;
 		slave_dev = dev_get_by_name( slave_name );
 		if( !slave_dev  ||  !(slave_dev->flags & IFF_UP) ) {
 			printk( KERN_ERR "%s: trying to enslave non-active "
 				"device %s\n", dev->name, slave_name );
 			return  -EPERM;
 		}
 
 		return  enslave( dev, slave_dev );
 
 	case  SIOCDEVEMANSIPATE :
+/* AUDIT-UL: should check a capability */
 		if( current->euid != 0 )	/* root only */
 			return  -EPERM;
 
 		return  emancipate( dev );
 
 #endif	/* CONFIG_SBNI_MULTILINE */
 
 	default :
 		return  -EOPNOTSUPP;
 	}
diff -rpU 10 linux-2.6.15.1.orig/drivers/s390/crypto/z90main.c linux-2.6.15.1/drivers/s390/crypto/z90main.c
--- linux-2.6.15.1.orig/drivers/s390/crypto/z90main.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/drivers/s390/crypto/z90main.c	Wed Jan 18 19:56:56 2006
@@ -1887,20 +1887,21 @@ z90crypt_unlocked_ioctl(struct file *fil
 				PRINTK("No longer issuing messages about depre"
 				       "cated ioctl Z90STAT_PCIXCCCOUNT.\n");
 		}
 
 		tempstat = get_status_PCIXCCcount();
 		if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
 			ret = -EFAULT;
 		break;
 
 	case Z90QUIESCE:
+/* AUDIT-UL: should check a capability */
 		if (current->euid != 0) {
 			PRINTK("QUIESCE fails: euid %d\n",
 			       current->euid);
 			ret = -EACCES;
 		} else {
 			PRINTK("QUIESCE device from PID %d\n", PID());
 			quiesce_z90crypt = 1;
 		}
 		break;
 
diff -rpU 10 linux-2.6.15.1.orig/fs/fcntl.c linux-2.6.15.1/fs/fcntl.c
--- linux-2.6.15.1.orig/fs/fcntl.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/fs/fcntl.c	Wed Jan 18 19:56:56 2006
@@ -414,20 +414,21 @@ static long band_table[NSIGPOLL] = {
 	POLLOUT | POLLWRNORM | POLLWRBAND,	/* POLL_OUT */
 	POLLIN | POLLRDNORM | POLLMSG,		/* POLL_MSG */
 	POLLERR,				/* POLL_ERR */
 	POLLPRI | POLLRDBAND,			/* POLL_PRI */
 	POLLHUP | POLLERR			/* POLL_HUP */
 };
 
 static inline int sigio_perm(struct task_struct *p,
                              struct fown_struct *fown, int sig)
 {
+/* AUDIT-UL: shouldn't this be checking a capability instead of euid == 0? */
 	return (((fown->euid == 0) ||
 		 (fown->euid == p->suid) || (fown->euid == p->uid) ||
 		 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
 		!security_file_send_sigiotask(p, fown, sig));
 }
 
 static void send_sigio_to_task(struct task_struct *p,
 			       struct fown_struct *fown, 
 			       int fd,
 			       int reason)
diff -rpU 10 linux-2.6.15.1.orig/fs/open.c linux-2.6.15.1/fs/open.c
--- linux-2.6.15.1.orig/fs/open.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/fs/open.c	Wed Jan 18 19:56:56 2006
@@ -492,20 +492,21 @@ asmlinkage long sys_access(const char __
 	current->fsgid = current->gid;
 
 	/*
 	 * Clear the capabilities if we switch to a non-root user
 	 *
 	 * FIXME: There is a race here against sys_capset.  The
 	 * capabilities can change yet we will restore the old
 	 * value below.  We should hold task_capabilities_lock,
 	 * but we cannot because user_path_walk can sleep.
 	 */
+/* AUDIT-UL: should also check for SECURE_NOROOT */
 	if (current->uid)
 		cap_clear(current->cap_effective);
 	else
 		current->cap_effective = current->cap_permitted;
 
 	res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
 	if (!res) {
 		res = vfs_permission(&nd, mode);
 		/* SuS v2 requires we report a read only fs too */
 		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
diff -rpU 10 linux-2.6.15.1.orig/kernel/sys.c linux-2.6.15.1/kernel/sys.c
--- linux-2.6.15.1.orig/kernel/sys.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/kernel/sys.c	Wed Jan 18 19:56:56 2006
@@ -669,20 +669,27 @@ asmlinkage long sys_setgid(gid_t gid)
 
 	key_fsgid_changed(current);
 	proc_id_connector(current, PROC_EVENT_GID);
 	return 0;
 }
   
 static int set_user(uid_t new_ruid, int dumpclear)
 {
 	struct user_struct *new_user;
 
+/* AUDIT-UM: This may cause setreuid, setuid, and setresuid to fail on
+ * transient errors, which older and/or poorly-written user-space apps
+ * might not expect.  A similar Linux 2.2 kernel problem is known to
+ * result in a root compromise with older versions of Sendmail:
+ * http://www.sendmail.org/sendmail.8.10.1.LINUX-SECURITY.txt
+ * That Linux 2.2 problem had been fixed, however this new one is
+ * introduced somewhere between 2.2 and 2.4... */
 	new_user = alloc_uid(new_ruid);
 	if (!new_user)
 		return -EAGAIN;
 
 	if (atomic_read(&new_user->processes) >=
 				current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
 			new_user != &root_user) {
 		free_uid(new_user);
 		return -EAGAIN;
 	}
diff -rpU 10 linux-2.6.15.1.orig/net/core/sock.c linux-2.6.15.1/net/core/sock.c
--- linux-2.6.15.1.orig/net/core/sock.c	Sun Jan 15 09:16:02 2006
+++ linux-2.6.15.1/net/core/sock.c	Wed Jan 18 19:56:56 2006
@@ -396,33 +396,41 @@ set_rcvbuf:
 
 			/* Bind this socket to a particular device like "eth0",
 			 * as specified in the passed interface name. If the
 			 * name is "" or the option length is zero the socket 
 			 * is not bound. 
 			 */ 
 
 			if (!valbool) {
 				sk->sk_bound_dev_if = 0;
 			} else {
+/* The check is signed, but that's OK due to optlen having been checked for
+ * possibly being negative right in sys_setsockopt(). */
 				if (optlen > IFNAMSIZ) 
 					optlen = IFNAMSIZ; 
 				if (copy_from_user(devname, optval, optlen)) {
 					ret = -EFAULT;
 					break;
 				}
 
 				/* Remove any cached route for this socket. */
 				sk_dst_reset(sk);
 
 				if (devname[0] == '\0') {
 					sk->sk_bound_dev_if = 0;
 				} else {
+/* AUDIT-UN: devname comes from userspace
+ * and it might not be NUL-terminated.  dev_get_by_name() uses strncmp() on it
+ * with IFNAMSIZ as the max length (good), however the actual number of bytes
+ * initialized in devname[] may be less than that (if optlen is less),
+ * resulting in the strncmp() checking uninitialized kernel stack space.
+ * Potential data leaks, one byte per 128 calls on average or better? */
 					struct net_device *dev = dev_get_by_name(devname);
 					if (!dev) {
 						ret = -ENODEV;
 						break;
 					}
 					sk->sk_bound_dev_if = dev->ifindex;
 					dev_put(dev);
 				}
 			}
 			break;

--n8g4imXOkfNTN/H1--

>From solar at openwall.com Thu Jan 19 14:53:40 2006
Date: Thu, 19 Jan 2006 14:53:40 +0300
From: Solar Designer <solar at openwall.com>
To: dev at sw.ru, st at sw.ru
Subject: [laforge at netfilter.org: netfilter do_replace() overflow]
Message-ID: <20060119115340.GA15281 at openwall.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.4.2.1i
Status: RO
Content-Length: 2788
Lines: 71

I'll respond to Harald now.

----- Forwarded message from Harald Welte <laforge at netfilter.org> -----

Date: Thu, 19 Jan 2006 09:57:04 +0100
From: Harald Welte <laforge at netfilter.org>
To: Solar Designer <solar at openwall.com>
Cc: coreteam at netfilter.org
Subject: netfilter do_replace() overflow

Hi Solar Designer,

JFYI:  This issue has actually been known, not to me personally but to
other members of the netfilter core team.

The point is, it has always been known that root can crash and/or do
other nasty things with ip_tables (and it's evil twins) anyway.

We don't do a big deal of checking on the data structure.  So by
carefully crafting an ip_tables structure and sending it via
setsockopt(), root can cause major breakage.

The underlying problem is that the kernel code doesn't really have any
code to really parse the data structure into all it's bits, and to
verify all the relative pointers/offsets used, etc.   It merely iterates
over that ugly blob.

The kind of checking we do (match/target parameters valid, no loops in
data structure, ...) are mostly to assure that there is no accidential
mistake by the admin or the userspace iptables program.

According to how I recall Rusty's statement with regard to this matter
at the last netfilter developer workshop, there seem to be many places
in the kernel where this kind of laziness of "well, he's root /
CAP_NET_ADMIN anway" exists.  At least there seem{s,ed} no general
policy about always veryfing everything that even root hands the kernel.

We [now] know that with OpenVZ like virtualization, this argument
doesn't really count anymore.

I just wanted to let you know about this, just in case you or anyone at
SWsoft has time to further investigate this issue.

We're certainly interested in helping you, but at least I myself am
currently terribly caught up in a number of [real world] issues, so my
time is a bit limited.  

If you wanted to prepare/push any kind of sophisticated
{ip,arp,ip6,eb}tables data structure verification patch, I would gladly
review and merge it.

Please also base any patches on 2.6.16-rc1, since there now is x_tables
- a first step in the direction of unifying {ip,ip6,arp} tables on the
  backend side.

Yes, the interface, the data structures and the N copies of it suck. I
always wanted to focus on writing something better rather than fixing
all the old stuff :(

Cheers,
	Harald
-- 
- Harald Welte <laforge at netfilter.org>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie



----- End forwarded message -----

>From solar at openwall.com Fri Mar 24 21:51:03 2006
Date: Fri, 24 Mar 2006 21:51:03 +0300
From: Solar Designer <solar at openwall.com>
To: Kirill Korotaev <dev at sw.ru>
Subject: Re: [AUDIT] assorted comments on Linux 2.6
Message-ID: <20060324185103.GA27643 at openwall.com>
References: <43CE507B.1090702 at sw.ru> <20060118173412.GA13580 at openwall.com> <20060323.224855.08427074.davem at davemloft.net> <4423B5B9.5060100 at sw.ru>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <4423B5B9.5060100 at sw.ru>
User-Agent: Mutt/1.4.2.1i
Status: RO
Content-Length: 1380
Lines: 35

On Fri, Mar 24, 2006 at 12:02:49PM +0300, Kirill Korotaev wrote:
> Sorry, did I miss something of forgot it?
> what is it about? :)

It was this bug:

+++ linux-2.6.8.1-ve022stab038-m/net/core/sock.c        Thu Oct 20 04:38:16 2005
[...]
@@ -384,6 +386,13 @@ int sock_setsockopt(struct socket *sock,
                                if (devname[0] == '\0') {
                                        sk->sk_bound_dev_if = 0;
                                } else {
+/* AUDIT-UN, AUDIT-VL: devname comes from userspace (is under VPS root control)
+ * and it might not be NUL-terminated.  dev_get_by_name() uses strncmp() on it
+ * with IFNAMSIZ as the max length (good), however the actual number of bytes
+ * initialized in devname[] may be less than that (if optlen is less),
+ * resulting in the strncmp() checking uninitialized kernel stack space.
+ * Potential data leaks, one bit per call? */
+/* dev_get_by_name() is VPS-aware - good */
                                        struct net_device *dev = dev_get_by_name (devname);

I think I was wrong about the leak rate - it's more like:

+ * Potential data leaks, one byte per 128 calls on average or better? */

as corrected in the 2.6.15.1 "patch" that I ended up submitting upstream.

> From S. David Miller:
> >I've taken care of the SO_BINDTODEVICE issue and will push
> >that fix around.
> >
> >Thanks!

-- 
Alexander



More information about the Users mailing list