Bugtraq mailing list archives

/dev/openprom problems - Solaris 1 or Solaris 2


From: matt () ott opcom ca (Matthew Harding)
Date: Fri, 24 May 1996 10:28:03 -0400


OK, OK, enough requests have flooded my mailbox that I will
post details here. Note that this issue actually affects
Solaris 1.x (aka SunOS 4.1.x) AS WELL AS Solaris 2.x.
However, in order to take advantage of this you need to
have read permissions to /dev/openprom. In SunOS 4.1.x the
default permissions were world-readable... bad!!! In Solaris
2.x these world-readable permissions were removed, but the
flaw still exists.


Note that this is a registered bugid with Sun (1222940) but
it is marked closed with no patch. Why? Because Sun's
solution for SunOS 4.1.x is to remove permissions from
/dev/openprom for unprivileged users, without actually fixing
the problem. No comment on this approach to "security"...


Synopsis
========

Any read access by unprivileged users can crash a Sparc,
REGARDLESS OF OPERATING SYSTEM (tested up to and
including Solaris 2.5).

This problem exists in SunOS 4.x (Solaris 1.x) as well as
Solaris 2.x.


The Problem
===========

The failure of the /dev/openprom code to check an
out-of-range pointer when dereferencing it causes the kernel
to panic. Note that only a READ of the /dev/openprom is
needed, not a write.


Exploit
=======

If you have contract access to SunSolve, you can read the
details of bugid 1222940 and compile the code fragment given
therein. Contract details prevent me from copying this
working code exploit.

However, the problem can be described quite easily. Anyone
can post a simple slice of code which can reproduce this
problem. As an example from the man pages on openprom:

    peer(int nodeid, int fd)
     {
          Oppbuf  oppbuf;
          struct openpromio *opp = &(oppbuf.opp);
          int *ip = (int *)(opp->oprom_array);

          (void) memset(oppbuf.buf, 0, BUFSZ);
          opp->oprom_size = MAXVALSZ;
(***)     *ip = nodeid;
          if (ioctl(fd, OPROMNEXT, opp) < 0) {
                  perror("OPROMNEXT");
                  exit(1);
          }
          return (*(int *)opp->oprom_array);
     }

The problem is that the /dev/openprom module does no bounds
checking on subsequent walks down the openprom tree. Thus if
we replace the (***) line with:

*ip = nodeid    with    *ip = some_out_of_range_integer,
                   i.e. *ip = 1283764732654

then we can cause /dev/openprom to panic.

Since everyone had read permission on the /dev/openprom
device in SunOS, anyone could crash the system. However,
although the permissions are fixed in Solaris 2 (why would an
unprivileged user need to access the raw openprom device?),
the PROBLEM STILL EXISTS!!!!


Solution
========

chmod /dev/openprom 400  (readable only by root).

Note an even more draconian method is to chmod it 000, the
only things this will break are programs like prtconf and
devinfo which walk the device tree in order to spew out
information about devices, etc. No great loss! Similar to
instructions for /dev/[k]mem... remove permissions
altogether!!! Ordinary users don't need access to these
things!!!


Sorry for the inability post a complete working exploit but I
don't believe the bugid 1222940 is available for public
consumption without a Sun contract. However, if any supreme
programming beings (*Hobbit?) wants to post a sample exploit
based on this info, go right ahead. Anyone?

Note if anyone still has questions, email me offline. This
one is nasty, causing an unconditional system panic.
Furthermore, it's the first bug I've seen which can crash any
Sparc from SunOS 4.1 all the way through Solaris 2.x. As far
as I know no plans are in place to make this a patch. Anyone
from Sun care to comment???

Regards,
Matthew (matt () ott opcom ca)



Current thread: