|
|
Subscribe / Log in / New account

Security

Virtual Machines and Memory Protections

November 20, 2006

This article was contributed by John Richard Moser

The IT industry and the open source community both currently enjoy a healthy want for security, a growing passion that has brought about new security tools and even some new programming languages. It isn't always easy to get all of these things working together; virtual machines such as Mono, for example, have difficulty with the memory space policies enforced by PaX or SELinux. Some implementations of the CLI virtual machine may have difficulty functioning with these security protections, and may be exposed to native code called from C# programs or the virtual machine itself.

The C# programming language is gaining popularity, and has been used to write programs such as Beagle, F-Spot, and Banshee. It is also a supported language for development in the GNOME environment. C# has strong type checking, array bounds checking, detection of attempts to use uninitialized variables, and automatic garbage collection, making it both type-safe and memory-safe; these aspects make it an attractive language for developers who want to sidestep manual memory management and just get their programs working.

C# programs are typically compiled to Common Instruction Language (CIL), a bytecode language designed to be run inside a virtual machine implementing the Common Language Infrastructure (CLI). Bytecode languages are similar to machine-level instructions, except they're not hosted on a physical CPU; effectively they are CPU architectures that are only run on emulators. Another familiar example of this is the Java platform, the typical target of the Java programming language.

The most naive approach to bytecode execution is to use an interpreter. Interpreters read each instruction in the program as executed; determine what the instruction is; and then modify the state of the virtual machine as needed, changing memory values or the program execution point. Interpreters execute dozens of instructions each time they process a bytecode instruction; programs execute very slowly, with all but the simplest being irritatingly sluggish.

Virtual machines often use a technique called Just-in-Time compilation (JIT) to improve performance. Rather than interpret, JIT compilers generate equivalent native code from the bytecode they encounter; in essence, they translate the parts of the program being run to run natively as encountered. Because of this, the continuous interpreter cost becomes a series of short one-time compilation costs, which in most cases goes unnoticed.

The first time I wrote for LWN, I authored a small article on security improving technologies which could be deployed now. Since then, these and other technologies have become more prevalent; ProPolice is part of gcc, and some of the concepts behind PaX and grsecurity are now integrated into products such as Exec Shield and SELinux. SELinux has policy elements that can be applied to almost exactly mimic the behavior of mprotect() under PaX.

Briefly put, both PaX and SELinux supply a set of protections that prevent programs from executing any memory that could have ever been directly altered by the program itself. A typical exploit technique is to use a flaw in a program to cause it to execute an area of memory an attacker loaded with code; with these restrictions, this attack is no longer possible. The attackers are forced then to resort to executing existing code out of order, which is a blind shot at a moving target due to address space randomization.

These protections are highly significant; however, they interfere in an unfortunate way with the execution of programs on Just-in-Time (JIT) mechanisms such as those used in Mono. The JIT needs to write code into memory and execute it; and the security system won't allow code generated at runtime to run. Since the interpreter is far too slow to be useful, the only real option is to disable the security mechanisms that interfere with the JIT.

The Common Language Infrastructure (CLI) allows for managed code to access unmanaged code; in other words, C# code can call plain old C libraries, making the program as a whole vulnerable to flaws that can't exist in C#. The implementation of the virtual machine is also a factor: Mono implements Web browser features using Mozilla's Gecko rendering engine; and Java implementations can, for example, use libpng bindings to supply PNG image handling rather than full managed rewrites.

Below are listed a couple popular Mono applications—C# and other CLI applications that run on Mono—using native libraries; as well as some of those libraries that have had significant security holes allowing remote runtime code execution.

With this potential for vulnerability, it would be attractive to find a solution for executing Mono without using the JIT. To execute CLI applications without a JIT, Mono would have to provide a method of executing assemblies without rewriting them into native code at runtime. This method would have to function both for typical CIL code and for dynamic assembly. Dynamic assembly is used to generate CIL bytecode at runtime, which is then executed by Mono with the help of the JIT. The Cecil debugger; IronPython; and the IKVM Java runtime are examples of programs that use dynamic assembly to execute whole programs.

The most naive method would be to switch back to the interpreter. Unfortunately we've already established that the interpreter is extremely slow, requiring dozens of cycles to complete even the simplest addition or variable assignment. Even if the interpreter didn't have such prohibitive performance issues, it's not really supported anywhere the JIT works, and isn't actively maintained.

Another possibility is to use the Ahead-of-Time (AOT) compiler to run Mono programs. The AOT compiles Mono assemblies to native code and stores them as shared libraries. AOT modules can be cached, verified, and updated as needed. This allows Mono to dlopen() the generated code and execute it like any other library. This not only eliminates runtime code generation; but also also increases code sharing between applications, reducing overall system memory usage. Unfortunately, dynamic assembly doesn't work with AOT, because it cannot be cached and verified later.

Ulrich Drepper described method of double-mapping a file, in which the same memory is available in two different places under two different permission sets. The file is created, opened, and unlinked so no other program can alter it; and then mmap() is used to make two shared mappings, one writable and one executable. This would work; but it would also increase disk access and use more of the task's virtual address space. It would also still allow a very obscure, unlikely, but possible method for directly introducing code into a program's address space and executing it successfully.

Currently there doesn't seem to be an obvious great solution to get Mono to run without runtime code generation. The interpreter is too slow; AOT doesn't cover dynamic assembly; and Drepper's method of double-mapping a file creates more disk access. Hybrid methods such as AOT with double-mapping for dynamic assemblies are also possible, reducing the severity of some of the drawbacks. By combining these methods, varying degrees of immunity to remote code execution are afforded with corresponding cost trade-offs.

Of interesting note is that double-mapping a file would prevent policy from being used to restrict the program to mapping only system libraries and a global AOT cache. Apart from the unlikely special case with double-mapping, enhanced memory protections will guarantee that an attacker cannot directly introduce code into a running program; however, attacks that use return-to-libc chains can still create, mmap(), and execute a file. To prevent this, one could restrict executable file-backed mappings to directories only the system administrator can write to, such as system libraries and a global AOT cache; of course, this would break double-mapping.

I cannot predict the implications of these facts for trusted systems and the applications of C# and Mono in high-security environments. For my own purposes, I would prohibit the use of Mono programs in environments with strong security requirements. In my perspective, the cost and potential for error involved in manually auditing all native code in both the Mono virtual machine and any native code used by Mono applications simply does not supply enough value; it is much easier to utilize protections against classes of vulnerabilities than to prove that applications do not need said protections. Your mileage may vary.

Comments (50 posted)

New vulnerabilities

elinks: arbitrary file access

Package(s):elinks CVE #(s):CVE-2006-5925
Created:November 16, 2006 Updated:October 22, 2009
Description: The elinks text-mode browser has an arbitrary file access vulnerability in the Elinks SMB protocol handler. If a user can be tricked into visiting a specially crafted web page, arbitrary files may be read or written with the user's permissions.
Alerts:
Ubuntu USN-851-1 elinks 2009-10-21
Gentoo 200701-27 elinks 2007-01-30
OpenPKG OpenPKG-SA-2006.043 links 2006-12-26
Debian DSA-1240-1 links2 2006-12-21
Gentoo 200612-16 links 2006-12-14
Debian DSA-1228-1 elinks 2006-12-05
Debian DSA-1226-1 links 2006-12-03
Fedora FEDORA-2006-1278 elinks 2006-11-21
Fedora FEDORA-2006-1277 elinks 2006-11-21
Mandriva MDKSA-2006:216 links 2006-11-20
Red Hat RHSA-2006:0742-01 elinks 2006-11-15

Comments (none posted)

flexbackup: insecure temporary file

Package(s):flexbackup CVE #(s):CVE-2006-4802
Created:November 21, 2006 Updated:November 21, 2006
Description: Eric Romang discovered that the flexbackup backup tool creates temporary files in an insecure manner, which allows denial of service through a symlink attack.
Alerts:
Debian DSA-1216-1 flexbackup 2006-11-20

Comments (none posted)

gv: stack-based buffer overflow

Package(s):gv CVE #(s):CVE-2006-5864
Created:November 20, 2006 Updated:April 9, 2007
Description: Stack-based buffer overflow in the ps_gettext function in ps.c for GNU gv 3.6.2, and possibly earlier versions, allows user-assisted attackers to execute arbitrary code via a PostScript (PS) file with certain headers that contain long comments, as demonstrated using the DocumentMedia header.
Alerts:
Gentoo 200704-06 evince 2007-04-06
Gentoo 200703-24 mgv 2007-03-26
Debian DSA-1243-1 evince 2006-12-28
Debian DSA-1214-2 gv 2006-12-27
Mandriva MDKSA-2006:229 evince 2006-12-13
rPath rPSA-2006-0230-1 evince 2006-12-12
Fedora FEDORA-2006-1438 evince 2006-12-11
Fedora FEDORA-2006-1437 evince 2006-12-11
Ubuntu USN-390-3 evince-gtk 2006-12-06
Ubuntu USN-390-2 evince 2006-12-06
Mandriva MDKSA-2006:214-1 gv 2006-12-04
Ubuntu USN-390-1 evince 2006-11-30
Gentoo 200611-20 gv 2006-11-24
Debian DSA-1214-1 gv 2006-11-20
Mandriva MDKSA-2006:214 gv 2006-11-17

Comments (none posted)

libpng: denial of service

Package(s):libpng CVE #(s):CVE-2006-5793
Created:November 16, 2006 Updated:December 4, 2006
Description: Applications that use libpng are vulnerable to a denial of service attack that may be brought about by the decoding of malformed PNG files.
Alerts:
Oracle ELSA-2012-0317 libpng 2012-02-21
rPath rPSA-2006-0211-2 libpng 2006-11-15
Slackware SSA:2006-335-03 libpng 2006-12-04
Gentoo 200611-09 libpng 2006-11-17
Trustix TSLSA-2006-0065 libpng 2006-11-17
Ubuntu USN-383-1 libpng 2006-11-16
OpenPKG OpenPKG-SA-2006.036 png 2006-11-17
Mandriva MDKSA-2006:212 doxygen 2006-11-16
Mandriva MDKSA-2006:211 pxelinux 2006-11-16
Mandriva MDKSA-2006:210 syslinux 2006-11-16
Mandriva MDKSA-2006:209 libpng 2006-11-16
rPath rPSA-2006-0211-1 libpng 2006-11-15

Comments (none posted)

proftpd: denial of service

Package(s):proftpd CVE #(s):CVE-2006-5815
Created:November 17, 2006 Updated:January 24, 2007
Description: A denial of service (DoS) vulnerability exists in the FTP server ProFTPD, up to and including version 1.3.0. The flaw is due to both a potential bus error and a definitive buffer overflow in the code which determines the FTP command buffer size limit. The vulnerability can be exploited only if the "CommandBufferSize" directive is explicitly used in the server configuration.
Alerts:
Mandriva MDKSA-2006:217-2 proftpd 2007-01-23
Trustix TSLSA-2006-0070 gnupg, proftpd 2006-12-08
Slackware SSA:2006-335-02 proftpd 2006-12-04
Debian DSA-1222-2 proftpd 2006-12-01
Gentoo 200611-26 proftpd 2006-11-30
Mandriva MDKSA-2006:217-1 proftpd 2006-11-30
Debian DSA-1222-1 proftpd 2006-11-30
Trustix TSLSA-2006-0066 openldap, proftpd 2006-11-28
Debian DSA-1218-1 proftpd 2006-11-21
Mandriva MDKSA-2006:217 proftpd 2006-11-20
OpenPKG OpenPKG-SA-2006.035 proftpd 2006-11-17

Comments (none posted)

qmailadmin: buffer overflow

Package(s):qmailadmin CVE #(s):CVE-2006-1141
Created:November 21, 2006 Updated:November 21, 2006
Description: qmailAdmin fails to properly handle the "PATH_INFO" variable in qmailadmin.c. The PATH_INFO is a standard CGI environment variable filled with user supplied data.
Alerts:
Gentoo 200611-15 qmailadmin 2006-11-21

Comments (none posted)

tikiwiki: multiple vulnerabilities

Package(s):tikiwiki CVE #(s):CVE-2006-5702 CVE-2006-5703
Created:November 21, 2006 Updated:November 21, 2006
Description: In numerous files TikiWiki provides an empty sort_mode parameter, causing TikiWiki to display additional information, including database authentication credentials, in certain error messages. TikiWiki also improperly sanitizes the "url" request variable sent to tiki-featured_link.php.
Alerts:
Gentoo 200611-11 tikiwiki 2006-11-20

Comments (none posted)

torque: insecure temporary file creation

Package(s):torque CVE #(s):CVE-2006-5677
Created:November 21, 2006 Updated:November 21, 2006
Description: TORQUE creates temporary files with predictable names. The TORQUE package shipped in Gentoo Portage is not vulnerable in the default configuration. Only systems with more permissive access rights to the spool directory are vulnerable.
Alerts:
Gentoo 200611-14 torque 2006-11-20

Comments (none posted)

Page editor: Jonathan Corbet
Next page: Kernel development>>


Copyright © 2006, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds