State Spill in Modern Operating Systems

Total Page:16

File Type:pdf, Size:1020Kb

State Spill in Modern Operating Systems A Characterization of State Spill in Modern Operating Systems Kevin Boos, Emilio Del Vecchio, and Lin Zhong Rice University fkevinaboos, edd5, [email protected] Abstract states change and propagate throughout the system, showing that modularity is necessary but insufficient. For example, Understanding and managing the propagation of states in several process migration works have cited “residual depen- operating systems has become an intractable problem due dencies” that remain on the source system as an obstacle to to their sheer size and complexity. Despite modularization post-migration correctness on the target system [38, 55, 34]. efforts, it remains a significant barrier to many contemporary Fault isolation and fault tolerance literature has long realized computing goals: process migration, fault isolation and the undesirable effects of fate sharing among software mod- tolerance, live update, software virtualization, and more. ules as well as the difficulty of restoring a process or whole Though many previous OS research endeavors have achieved machine statefully after a failure, due to the sprawl of states these goals through ad-hoc, tedious methods, we argue that spread among different system components [28, 26, 52, 51]. they have missed the underlying reason why these goals are Live update and hot-swapping research has long sought to overcome the state maintenance issues and inter-module de- so challenging: state spill. pendencies that plague their implementations when transi- State spill occurs when a software entity’s state undergoes tioning from an old to a new version, forcing developers to lasting changes as a result of a transaction from another entity. write complex state transfer functions [7, 25, 27, 48, 5]. Like- In order to increase awareness of state spill and its harmful wise, state management poses a problem to the virtualization effects, we conduct a thorough study of modern OSes and of arbitrary software components, significantly complicat- contribute a classification of design patterns that cause state ing the multiplexing and isolation logic of the underlying spill. We present STATESPY, an automated tool that leverages virtualization layer (e.g., kernel or runtime) [11, 6]. cooperative static and runtime analysis to detect state spill in In this paper, our primary contribution is to identify the real software entities. Guided by STATESPY, we demonstrate problem of state spill as a root cause of these problems and the presence of state spill in 94% of Android system services. show that it is the underlying reason why many computing Finally, we analyze the harmful impacts of state spill and goals are so difficult to realize, even in the face of proper mod- ularization. State spill is the act of one software entity’s state suggest alternative designs and strategies to mitigate them. undergoing lasting changes as a result of its interaction with 1. Introduction another entity. For example, if an application interacts with a system service, causing that service to store application- Over the past few decades, operating systems research has relevant states in its memory, then state spill has occurred gone to great lengths to achieve a spectrum of advanced com- from the application to the service. We formally define state puting goals: process migration, fault isolation and tolerance, spill and the conditions under which it occurs in §3. live update, hot-swapping, virtualization, security, general From this cursory explanation, it is apparent that state spill maintainability, and more. Better modularization, in which is a phenomenon that permeates all levels of a software sys- related functionality is grouped into bounded entities, is often tem. However, it is relative to the choice of entity granularity: touted as the most apt solution for realizing such goals, and it interactions that cross the boundary of an entity are consid- seems promising from an initial glance. However, we argue ered transactions of interest, but those within a single entity that modularization alone is not enough, and that the effects are not. As an example, if the entity granularity is defined to of interactions between modules have a more pronounced be a process, then an IPC call between two processes could impact on these goals, as shown below. constitute state spill, but a local function call within a process Many efforts towards these goals have been ad-hoc and could not. The definition of state spill is not confined to any platform-specific due to the complex nature of how software particular entity granularity; entity granularity is a platform- and goal-specific decision (§3.1). However, in this work, our analysis centers around entity bounds akin to those of a mod- ule: an entity consists of a group of related functions and the Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice data they modify. When analyzing Android system services, and the full citation on the first page. Copyrights for components of this work owned by others than the author(s) must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to for example, the best entity granularity choice is a Java class. lists, requires prior specific permission and/or a fee. Request permissions from [email protected]. The second contribution of this work is a manual analysis EuroSys ’17, April 23 - 26, 2017, Belgrade, Serbia of state spill and its detrimental impact on the aforementioned © 2017 Copyright held by the owner/author(s). Publication rights licensed to ACM. ISBN 978-1-4503-4938-3/17/04. $15.00 computing goals across various real-world OSes. We find that DOI: http://dx.doi.org/10.1145/3064176.3064205 state spill is often a byproduct of applying the locality prin- Definition 1. A transaction is the flow of control (and ciple to OS design, in that it often stems from design choices optionally data) from one software entity to another. The that favor programming convenience or performance over ad- source entity, or client, initiates the transaction and the herence to strict architectural or modularity principles. Based destination entity, or server, receives and handles it, returning on these case studies, we establish a classification of state spill control to the source upon completion. (§4) according to common design patterns: indirection layers, Transactions can represent procedure calls, system calls, multiplexers, dispatchers, and inter-entity collaboration. interrupts, signals, other IPC, and more. The exact incarnation Our third contribution is the STATESPY tool that auto- of a transaction is defined by which entities are involved; for mates the detection of state spill in real systems, and an in- example, a function call is a transaction from one function depth, tool-guided analysis of state spill in Android’s system to another function in the same thread; system calls are service entities. As described in §5, STATESPY employs both transactions from a userspace entity to a kernelspace one; runtime and static analysis techniques that automate the cap- IPC is a transaction from one process to another. Transactions ture, inspection, and differencing of a software entity’s state, have the following explicitly-defined characteristics: with current support for Java environments. The runtime anal- ysis component of STATESPY captures a running entity’s state • If a transaction is interrupted (e.g., preempted), it is simply by interposing on an entity’s execution paths when handling treated as incomplete until it resumes and returns control. transactions invoked by real-world applications. Our key in- • If a transaction never completes, such as a call to an debugging sight for runtime analysis is to leverage existing endlessly-looping function that listens for messages, no frameworks to non-intrusively capture and compare entity future actions from different source entities can be affected states, a technique that forgoes environment-specific features by its changes; thus, it is irrelevant to state spill. and generalizes to any execution environment. The static anal- ysis component of STATESPY provides relevancy filters to the • If a transaction handler fails, e.g., by returning an error, it runtime component as part of a cooperative feedback loop that is treated the same as a completed successful transaction. iteratively improves the output of each component. Guided • If a transaction is asynchronous/non-blocking, it is treated by STATESPY, our experimental analysis of Android system as two separate ones: an initial transaction from the source services (§6) finds that harmful state spill is both prevalent to the destination, and a second transaction from the and deep: nearly all Android system services have state spill, destination back to the source as a completion event. and it often occurs in a chain across multiple services. We discuss how to mitigate the effects of state spill in §7 We are primarily interested in short-lived transactions that by rethinking existing software designs patterns and commu- leave a lasting change on the destination entity, such that the nication schemes. Modularization is not enough: reducing latter’s future behavior will be affected. the impact of state spill is key to simplifying software com- 2.2 Quiescence in Software Entities ponents and making them amenable to migration, live update, fault recovery, virtualization, and other computing goals. In In assessing state spill, we are interested in the effect of a fact, we have shown Android system services can be made single transaction on an entity; thus an entity’s state is only more fault tolerant with state spill mitigation techniques [17]. matters at certain points: before and after a transaction, not In summary, we identify and formally define the problem during. We use the concept of quiescence to identify this of state spill in modern OSes, classify its various incarnations, condition.
Recommended publications
  • Yutaka Oiwa. "Implementation of a Fail-Safe ANSI C Compiler"
    Implementation of a Fail-Safe ANSI C Compiler 安全な ANSI C コンパイラの実装手法 Doctoral Dissertation 博士論文 Yutaka Oiwa 大岩 寛 Submitted to Department of Computer Science, Graduate School of Information Science and Technology, The University of Tokyo on December 16, 2004 in partial fulfillment of the requirements for the degree of Doctor of Philosophy Abstract Programs written in the C language often suffer from nasty errors due to dangling pointers and buffer overflow. Such errors in Internet server programs are often ex- ploited by malicious attackers to “crack” an entire system, and this has become a problem affecting society as a whole. The root of these errors is usually corruption of on-memory data structures caused by out-of-bound array accesses. The C lan- guage does not provide any protection against such out-of-bound access, although recent languages such as Java, C#, Lisp and ML provide such protection. Never- theless, the C language itself should not be blamed for this shortcoming—it was designed to provide a replacement for assembly languages (i.e., to provide flexible direct memory access through a light-weight high-level language). In other words, lack of array boundary protection is “by design.” In addition, the C language was designed more than thirty years ago when there was not enough computer power to perform a memory boundary check for every memory access. The real prob- lem is the use of the C language for current casual programming, which does not usually require such direct memory accesses. We cannot realistically discard the C language right away, though, because there are many legacy programs written in the C language and many legacy programmers accustomed to the C language and its programming style.
    [Show full text]
  • WWW-Based Collaboration Environments with Distributed Tool Services
    WWWbased Collab oration Environments with Distributed To ol Services Gail E Kaiser Stephen E Dossick Wenyu Jiang Jack Jingshuang Yang SonnyXiYe Columbia University Department of Computer Science Amsterdam Avenue Mail Co de New York NY UNITED STATES fax kaisercscolumbiaedu CUCS February Abstract Wehave develop ed an architecture and realization of a framework for hyp ermedia collab oration environments that supp ort purp oseful work by orchestrated teams The hyp ermedia represents all plausible multimedia artifacts concerned with the collab orative tasks at hand that can b e placed or generated online from applicationsp ecic materials eg source co de chip layouts blueprints to formal do cumentation to digital library resources to informal email and chat transcripts The environment capabilities include b oth internal hyp ertext and external link server links among these artifacts which can b e added incrementally as useful connections are discovered pro jectsp ecic hyp ermedia search and browsing automated construction of artifacts and hyp erlinks according to the semantics of the group and individual tasks and the overall pro cess workow application of to ols to the artifacts and collab orativework for geographically disp ersed teams We present a general architecture for what wecallhyp ermedia subwebs and imp osition of groupspace services op erating on shared subwebs based on World Wide Web technology which could b e applied over the Internet andor within an organizational intranet We describ e our realization in OzWeb which
    [Show full text]
  • Intra-Unikernel Isolation with Intel Memory Protection Keys
    Intra-Unikernel Isolation with Intel Memory Protection Keys Mincheol Sung Pierre Olivier∗ Virginia Tech, USA The University of Manchester, United Kingdom [email protected] [email protected] Stefan Lankes Binoy Ravindran RWTH Aachen University, Germany Virginia Tech, USA [email protected] [email protected] Abstract ACM Reference Format: Mincheol Sung, Pierre Olivier, Stefan Lankes, and Binoy Ravin- Unikernels are minimal, single-purpose virtual machines. dran. 2020. Intra-Unikernel Isolation with Intel Memory Protec- This new operating system model promises numerous bene- tion Keys. In 16th ACM SIGPLAN/SIGOPS International Conference fits within many application domains in terms of lightweight- on Virtual Execution Environments (VEE ’20), March 17, 2020, Lau- ness, performance, and security. Although the isolation be- sanne, Switzerland. ACM, New York, NY, USA, 14 pages. https: tween unikernels is generally recognized as strong, there //doi.org/10.1145/3381052.3381326 is no isolation within a unikernel itself. This is due to the use of a single, unprotected address space, a basic principle 1 Introduction of unikernels that provide their lightweightness and perfor- Unikernels have gained attention in the academic research mance benefits. In this paper, we propose a new design that community, offering multiple benefits in terms of improved brings memory isolation inside a unikernel instance while performance, increased security, reduced costs, etc. As a keeping a single address space. We leverage Intel’s Memory result,
    [Show full text]
  • A Linux in Unikernel Clothing Lupine
    A Linux in Unikernel Clothing Hsuan-Chi Kuo+, Dan Williams*, Ricardo Koller* and Sibin Mohan+ +University of Illinois at Urbana-Champaign *IBM Research Lupine Unikernels are great BUT: Unikernels lack full Linux Support App ● Hermitux: supports only 97 system calls Kernel LibOS + App ● OSv: ○ Fork() , execve() are not supported Hypervisor Hypervisor ○ Special files are not supported such as /proc ○ Signal mechanism is not complete ● Small kernel size ● Rumprun: only 37 curated applications ● Heavy ● Fast boot time ● Community is too small to keep it rolling ● Inefficient ● Improved performance ● Better security 2 Can Linux behave like a unikernel? 3 Lupine Linux 4 Lupine Linux ● Kernel mode Linux (KML) ○ Enables normal user process to run in kernel mode ○ Processes can still use system services such as paging and scheduling ○ App calls kernel routines directly without privilege transition costs ● Minimal patch to libc ○ Replace syscall instruction to call ○ The address of the called function is exported by the patched KML kernel using the vsyscall ○ No application changes/recompilation required 5 Boot time Evaluation Metrics Image size Based on: Unikernel benefits Memory footprint Application performance Syscall overhead 6 Configuration diversity ● 20 top apps on Docker hub (83% of all downloads) ● Only 19 configuration options required to run all 20 applications: lupine-general 7 Evaluation - Comparison configurations Lupine Cloud Operating Systems [Lupine-base + app-specific options] OSv general Linux-based Unikernels Kernel for 20 apps
    [Show full text]
  • Unikernel Monitors: Extending Minimalism Outside of the Box
    Unikernel Monitors: Extending Minimalism Outside of the Box Dan Williams Ricardo Koller IBM T.J. Watson Research Center Abstract Recently, unikernels have emerged as an exploration of minimalist software stacks to improve the security of ap- plications in the cloud. In this paper, we propose ex- tending the notion of minimalism beyond an individual virtual machine to include the underlying monitor and the interface it exposes. We propose unikernel monitors. Each unikernel is bundled with a tiny, specialized mon- itor that only contains what the unikernel needs both in terms of interface and implementation. Unikernel mon- itors improve isolation through minimal interfaces, re- Figure 1: The unit of execution in the cloud as (a) a duce complexity, and boot unikernels quickly. Our ini- unikernel, built from only what it needs, running on a tial prototype, ukvm, is less than 5% the code size of a VM abstraction; or (b) a unikernel running on a spe- traditional monitor, and boots MirageOS unikernels in as cialized unikernel monitor implementing only what the little as 10ms (8× faster than a traditional monitor). unikernel needs. 1 Introduction the application (unikernel) and the rest of the system, as defined by the virtual hardware abstraction, minimal? Minimal software stacks are changing the way we think Can application dependencies be tracked through the in- about assembling applications for the cloud. A minimal terface and even define a minimal virtual machine mon- amount of software implies a reduced attack surface and itor (or in this case a unikernel monitor) for the applica- a better understanding of the system, leading to increased tion, thus producing a maximally isolated, minimal exe- security.
    [Show full text]
  • LISTSERV 16.0 Site Manager's Operations Manual
    Information in this document is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. L-Soft does not endorse or approve the use of any of the product names or trademarks appearing in this document. Permission is granted to copy this document, at no charge and in its entirety, if the copies are not used for commercial advantage, the source is cited, and the present copyright notice is included in all copies. Recipients of such copies are equally bound to abide by the present conditions. Prior written permission is required for any commercial use of this document, in whole or in part, and for any partial reproduction of the contents of this document exceeding 50 lines of up to 80 characters, or equivalent. The title page, table of contents, and index, if any, are not considered to be part of the document for the purposes of this copyright notice, and can be freely removed if present. Copyright 2009 L-Soft international, Inc. All Rights Reserved Worldwide. LISTSERV is a registered trademark licensed to L-Soft international, Inc. ListPlex, CataList, and EASE are service marks of L-Soft international, Inc. LSMTP is a registered trademark of L-Soft international, Inc. The Open Group, Motif, OSF/1 UNIX and the “X” device are registered trademarks of The Open Group in the United State and other countries. Digital, Alpha AXP, AXP, Digital UNIX, OpenVMS, HP, and HP-UX are trademarks of Hewlett- Packard Company in the United States and other countries. Microsoft, Windows, Windows 2000, Windows XP, and Windows NT are registered trademarks of Microsoft Corporation in the United States and other countries.
    [Show full text]
  • Microkernel Construction Introduction
    Microkernel Construction Introduction Nils Asmussen 04/09/2020 1 / 32 Normal Organization Thursday, 4th DS, 2 SWS Slides: www.tudos.org ! Studies ! Lectures ! MKC Subscribe to our mailing list: www.tudos.org/mailman/listinfo/mkc2020 In winter term: Microkernel-based operating systems (MOS) Various labs 2 / 32 Organization due to COVID-19 Slides and video recordings of lectures will be published Questions can be asked on the mailing list Subscribe to the mailing list! Practical exercises are planed for the end of the semester Depending on how COVID-19 continues, exercises are in person or we use some video-conferencing tool 3 / 32 Goals 1 Provide deeper understanding of OS mechanisms 2 Look at the implementation details of microkernels 3 Make you become enthusiastic microkernel hackers 4 Propaganda for OS research done at TU Dresden and Barkhausen Institut 4 / 32 Outline Organization Monolithic vs. Microkernel Kernel design comparison Examples for microkernel-based systems Vision vs. Reality Challenges Overview About L4/NOVA 5 / 32 Monolithic Kernel System Design u s Application Application Application e r k Kernel e r File Network n e Systems Stacks l m Memory Process o Drivers Management Management d e Hardware 6 / 32 Monolithic Kernel OS (Propaganda) System components run in privileged mode No protection between system components Faulty driver can crash the whole system Malicious app could exploit bug in faulty driver More than 2=3 of today's OS code are drivers No need for good system design Direct access to data structures Undocumented
    [Show full text]
  • Cognitive Abilities, Interfaces and Tasks: Effects on Prospective Information Handling in Email
    Cognitive Abilities, Interfaces and Tasks: Effects on Prospective Information Handling in Email by Jacek Stanisław Gwizdka A thesis submitted in conformity with the requirements for the degree of Doctor of Philosophy Graduate Department of Mechanical and Industrial Engineering University of Toronto © Copyright by Jacek Gwizdka 2004 “Cognitive Abilities, Interfaces and Tasks: Effects on Prospective Information Handling in Email” Degree of Doctor of Philosophy, 2004 Jacek Stanisław Gwizdka Department of Mechanical and Industrial Engineering, University of Toronto Abstract This dissertation is focused on new email user interfaces that may improve awareness and handling of task-laden messages in the inbox. The practical motivation for this research was to help email users process messages more effectively. A field study was conducted to examine email practices related to handling messages that refer to pending tasks. Individual differences in message handling style were observed, with one group of users transferring such messages out of their email pro- grams to other applications (e.g., calendars), while the other group kept prospective messages in email and used the inbox as a reminder of future events. Two novel graphical user interfaces were designed to facilitate monitoring and retrieval of prospective information from email messages. The TaskView interface displayed task- laden messages on a two-dimensional grid (with time on the horizontal axis). The WebT- askMail interface retained the two-dimensional grid, but extended the representation of pending tasks (added distinction between events and to-do's with deadlines), a vertical date reading line, and more space for email message headers. ii Two user studies were conducted to test hypothesized benefits of the new visual repre- sentations and to examine the effects of different levels of selected cognitive abilities on task-laden message handling performance.
    [Show full text]
  • Unix Quickref.Dvi
    Summary of UNIX commands Table of Contents df [dirname] display free disk space. If dirname is omitted, 1. Directory and file commands 1994,1995,1996 Budi Rahardjo ([email protected]) display all available disks. The output maybe This is a summary of UNIX commands available 2. Print-related commands in blocks or in Kbytes. Use df -k in Solaris. on most UNIX systems. Depending on the config- uration, some of the commands may be unavailable 3. Miscellaneous commands du [dirname] on your site. These commands may be a commer- display disk usage. cial program, freeware or public domain program that 4. Process management must be installed separately, or probably just not in less filename your search path. Check your local documentation or 5. File archive and compression display filename one screenful. A pager similar manual pages for more details (e.g. man program- to (better than) more. 6. Text editors name). This reference card, obviously, cannot de- ls [dirname] scribe all UNIX commands in details, but instead I 7. Mail programs picked commands that are useful and interesting from list the content of directory dirname. Options: a user's point of view. 8. Usnet news -a display hidden files, -l display in long format 9. File transfer and remote access mkdir dirname Disclaimer make directory dirname The author makes no warranty of any kind, expressed 10. X window or implied, including the warranties of merchantabil- more filename 11. Graph, Plot, Image processing tools ity or fitness for a particular purpose, with regard to view file filename one screenfull at a time the use of commands contained in this reference card.
    [Show full text]
  • Can Microkernels Mitigate Microarchitectural Attacks?⋆
    Can Microkernels Mitigate Microarchitectural Attacks?? Gunnar Grimsdal1, Patrik Lundgren2, Christian Vestlund3, Felipe Boeira1, and Mikael Asplund1[0000−0003−1916−3398] 1 Department of Computer and Information Science, Link¨oping University, Sweden ffelipe.boeira,[email protected] 2 Westermo Network Technologies [email protected] 3 Sectra AB, Link¨oping,Sweden Abstract. Microarchitectural attacks such as Meltdown and Spectre have attracted much attention recently. In this paper we study how effec- tive these attacks are on the Genode microkernel framework using three different kernels, Okl4, Nova, and Linux. We try to answer the question whether the strict process separation provided by Genode combined with security-oriented kernels such as Okl4 and Nova can mitigate microar- chitectural attacks. We evaluate the attack effectiveness by measuring the throughput of data transfer that violates the security properties of the system. Our results show that the underlying side-channel attack Flush+Reload used in both Meltdown and Spectre, is effective on all in- vestigated platforms. We were also able to achieve high throughput using the Spectre attack, but we were not able to show any effective Meltdown attack on Okl4 or Nova. Keywords: Genode, Meltdown, Spectre, Flush+Reload, Okl4, Nova 1 Introduction It used to be the case that general-purpose operating systems were mostly found in desktop computers and servers. However, as IoT devices are becoming in- creasingly more sophisticated, they tend more and more to require a powerful operating system such as Linux, since otherwise all basic services must be im- plemented and maintained by the device developers. At the same time, security has become a prime concern both in IoT and in the cloud domain.
    [Show full text]
  • Operating System Support for Run-Time Security with a Trusted Execution Environment
    Operating System Support for Run-Time Security with a Trusted Execution Environment - Usage Control and Trusted Storage for Linux-based Systems - by Javier Gonz´alez Ph.D Thesis IT University of Copenhagen Advisor: Philippe Bonnet Submitted: January 31, 2015 Last Revision: May 30, 2015 ITU DS-nummer: D-2015-107 ISSN: 1602-3536 ISBN: 978-87-7949-302-5 1 Contents Preface8 1 Introduction 10 1.1 Context....................................... 10 1.2 Problem....................................... 12 1.3 Approach...................................... 14 1.4 Contribution.................................... 15 1.5 Thesis Structure.................................. 16 I State of the Art 18 2 Trusted Execution Environments 20 2.1 Smart Cards.................................... 21 2.1.1 Secure Element............................... 23 2.2 Trusted Platform Module (TPM)......................... 23 2.3 Intel Security Extensions.............................. 26 2.3.1 Intel TXT.................................. 26 2.3.2 Intel SGX.................................. 27 2.4 ARM TrustZone.................................. 29 2.5 Other Techniques.................................. 32 2.5.1 Hardware Replication........................... 32 2.5.2 Hardware Virtualization.......................... 33 2.5.3 Only Software............................... 33 2.6 Discussion...................................... 33 3 Run-Time Security 36 3.1 Access and Usage Control............................. 36 3.2 Data Protection................................... 39 3.3 Reference
    [Show full text]
  • Site Manager's Operations Manual for LISTSERV®, Version 14.3
    L-Soft international, Inc. Site Manager's Operations Manual for LISTSERV®, version 14.3 7 December 2004 LISTSERV 14.3 Release The reference number of this document is 0412-MD-01. Information in this document is subject to change without notice. Companies, names and data used in examples herein are fictitious unless otherwise noted. L-Soft international, Inc. does not endorse or approve the use of any of the product names or trademarks appearing in this document. Permission is granted to copy this document, at no charge and in its entirety, provided that the copies are not used for commercial advantage, that the source is cited and that the present copyright notice is included in all copies, so that the recipients of such copies are equally bound to abide by the present conditions. Prior written permission is required for any commercial use of this document, in whole or in part, and for any partial reproduction of the contents of this document exceeding 50 lines of up to 80 characters, or equivalent. The title page, table of contents and index, if any, are not considered to be part of the document for the purposes of this copyright notice, and can be freely removed if present. The purpose of this copyright is to protect your right to make free copies of this manual for your friends and colleagues, to prevent publishers from using it for commercial advantage, and to prevent ill-meaning people from altering the meaning of the document by changing or removing a few paragraphs. Copyright © 1996-2004 L-Soft international, Inc.
    [Show full text]