TIMBER-V: Tag-Isolated Memory Bringing Fine-Grained Enclaves to RISC-V

Total Page:16

File Type:pdf, Size:1020Kb

TIMBER-V: Tag-Isolated Memory Bringing Fine-Grained Enclaves to RISC-V TIMBER-V: Tag-Isolated Memory Bringing Fine-grained Enclaves to RISC-V Samuel Weiser∗, Mario Werner∗, Ferdinand Brassery, Maja Malenko∗, Stefan Mangard∗, Ahmad-Reza Sadeghiy ∗ Graz University of Technology: fsamuel.weiser, mario.werner, [email protected], [email protected] y TU Darmstadt: [email protected], [email protected]. Abstract—Embedded computing devices are used on a large resource-constrained devices often suffer from poor memory scale in the emerging internet of things (IoT). However, their utilization due to memory fragmentation and inefficient isola- wide deployment raises the incentive for attackers to target these tion mechanisms. A tighter integration of trusted memory in devices, as demonstrated by several recent attacks. As IoT devices the limited physical address space would demand fine-grained are built for long service life, means are required to protect sen- isolation boundaries, which existing schemes either do not pro- sitive code in the presence of potential vulnerabilities, which might vide at all, or provide only at the expense of high management be discovered long after deployment. Tagged memory has been proposed as a mechanism to enforce various fine-grained security overhead. Also, more flexible isolation mechanisms are impor- policies at runtime. However, none of the existing tagged memory tant for dynamically managing trusted memory. A technique schemes provides efficient and flexible compartmentalization in that has the potential to offer fine-grained and flexible isolation terms of isolated execution environments. boundaries is tagged memory. Tagged memory transparently associates blocks of memory with additional metadata. It has We present TIMBER-V, a new tagged memory architecture been used for dynamic information flow tracking [48] as featuring flexible and efficient isolation of code and data on small well as access control [53], and is still an active subject of embedded systems. We overcome several limitations of previous schemes. We augment tag isolation with a memory protection research [31,45]. While tagged memory has been shown to unit to isolate individual processes, while maintaining low mem- support a variety of security policies like protection of control ory overhead. TIMBER-V significantly reduces the problem of data [14], pointers [18] or capabilities [52], strong, efficient memory fragmentation, and improves dynamic reuse of untrusted and flexible isolated execution is still an open problem for memory across security boundaries. TIMBER-V enables novel small embedded systems. In particular, data flow isolation [45] sharing of execution stacks across different security domains, cannot provide strong isolation since tags can be destructively in addition to interleaved heaps. TIMBER-V is compatible to written by untrusted software. Other existing solutions are not existing code, supports real-time constraints and is open source. appropriate for low-end embedded devices due to their memory We show the efficiency of TIMBER-V by evaluating our proof- overhead stemming from large tags [54] or fully programmable of-concept implementation on the RISC-V simulator. but expensive tag engines [11,17,19,49]. Hence, currently no existing tagged memory schemes supports efficient isolated I. INTRODUCTION execution on small embedded devices. With ongoing advances in miniaturization and energy ef- In this work, we propose TIMBER-V, a tagged memory ficiency, computing devices are rapidly penetrating everyday architecture which brings efficient isolated execution in form life. Due to long service life, security of such devices becomes of enclaves to low-end devices. Since isolated execution is decisive. In in the recent past, we have been witnessing attacks still not well researched for low-end RISC-V processors, we on millions of cameras and routers [39], cars [38], cardiac prototype TIMBER-V on the open RISC-V architecture via devices [35] and light bulbs [41], to name a few. The high a hardware-software co-design. On the hardware side, we code complexity of these devices fosters programming bugs, achieve fine-grained in-process isolation with only two tag making their exploitation only a matter of time. This atten- bits. Moreover, we combine tagged memory with a memory uates potential IoT use cases since a compromise could have protection unit (MPU) to support an arbitrary number of immediate monetary, legal or privacy consequences [26]. Also, processes while avoiding the overhead of large tags [54]. the protection of intellectual property (IP) in a highly diverse On the software side, we enforce isolated execution via a market like the IoT, which integrates code from multiple small trust manager, called TagRoot. We isolate privileged vendors, requires strong security guarantees. from unprivileged security domains, supporting both, Intel SGX enclaves [37] and the TrustZone [3] programming model, Isolated execution protects sensitive code and data on however, with much finer isolation granularity and more ef- devices with compromised or untrusted software, and has been ficient memory utilization. This has several advantages. On proposed for different systems, with and without virtual mem- the one hand, data locality can be maintained by interleav- ory [2,3,7,9,10,13,21,22,25,28,34,37,40,47]. Especially small ing trusted and untrusted memory, thus minimizing memory fragmentation. On the other hand, TIMBER-V uses a tag update policy which allows highly flexible dynamic memory Network and Distributed Systems Security (NDSS) Symposium 2019 management of trusted data. Dynamic memory support has 24-27 February 2019, San Diego, CA, USA ISBN 1-891562-55-X been announced for the upcoming Intel SGXv2 which involves https://dx.doi.org/10.14722/ndss.2019.23068 costly interaction with the operating system [29]. In contrast, www.ndss-symposium.org TIMBER-V enclaves can instantaneously claim memory by using a single instruction. To demonstrate these advantages, monitor handler to switch worlds. ARM TrustZone-M [3] we show heap interleaving and a novel stack interleaving integrates the TrustZone concept into smaller Cortex-M pro- scheme. That is, we use a single heap and stack across different cessors. Non-secure applications can call secure applications security domains while maintaining strong isolation. Moreover, through multiple designated entry points, specified via non- we demonstrate highly efficient inter-enclave communication secure callable regions. over secure shared memory. We support real-time constraints by making all trusted software interruptible. We implement and The central concept of Intel SGX [37] is a hardware- benchmark TIMBER-V on the RISC-V Spike simulator, allow- isolated container, called an enclave, in which sensitive parts ing an evaluation under different CPU models which highlights of an application are placed. Unlike TrustZone, an enclave characteristics of TIMBER-V rather than CPU implementation directly resides in the address space of a user process. SGX specifics. We show that the runtime overhead of TIMBER-V does not rely on any privileged software (trusted kernel, is 25.2% for naive implementations while tag caching reduces hypervisor, etc.) to isolate enclaves, thus reducing the TCB the overhead to 2.6%. to only the CPU and enclaves themselves. However, SGX’s management instructions involve pretty complex microcode. In summary, our main contributions are: RISC-V. RISC-V [50] is an open and extensible instruction • We propose TIMBER-V, the first efficient tagged memory set architecture and defines three privilege modes [51], namely architecture for isolated execution on low-end processors machine-mode (M), supervisor-mode (S), and user-mode (U). • We present a novel concept called stack interleaving that M-mode has the highest privileges and is used for emulating allows for efficient and dynamic memory management missing hardware features. S-mode and U-mode are meant to • We propose lightweight shared memory between enclaves run an operating system and user applications, respectively. • We propose an efficient shared MPU design • We extensively evaluated our proof-of-concept implemen- Tagged Memory. The idea behind tagged memory is to extend tation1 on the RISC-V simulator for different CPU models each memory word with additional bits that store metadata. The general tagged architecture concept is very old and can already be found in numerous early computer designs [23]. II. BACKGROUND There, tag bits were, for example, used for debugging as well This section gives background information about related as for dynamically tracking the numeric type of data words. security architectures, RISC-V and tagged memory. Recent commercially available computer architectures hardly support hardware-based tagged memory. Schemes that asso- Security Architectures. Process isolation is a fundamental ciate memory with metadata, like for example dynamic analy- security concept which combines hardware and software tech- sis tools [43,44,46], rely on software-based solutions instead. niques to isolate the memory of processes from each other. It However, recent research on tagged-memory architectures in is usually enforced by the operating system taking advantage the system security context [8,19,45] hints that re-establishing of processor’s privilege modes. Large systems isolate pro- hardware-support can considerably improve security. cesses in separate virtual address spaces with the help of a memory management unit (MMU), while resource-constrained devices use a memory protection
Recommended publications
  • Memory Protection at Option
    Memory Protection at Option Application-Tailored Memory Safety in Safety-Critical Embedded Systems – Speicherschutz nach Wahl Auf die Anwendung zugeschnittene Speichersicherheit in sicherheitskritischen eingebetteten Systemen Der Technischen Fakultät der Universität Erlangen-Nürnberg zur Erlangung des Grades Doktor-Ingenieur vorgelegt von Michael Stilkerich Erlangen — 2012 Als Dissertation genehmigt von der Technischen Fakultät Universität Erlangen-Nürnberg Tag der Einreichung: 09.07.2012 Tag der Promotion: 30.11.2012 Dekan: Prof. Dr.-Ing. Marion Merklein Berichterstatter: Prof. Dr.-Ing. Wolfgang Schröder-Preikschat Prof. Dr. Michael Philippsen Abstract With the increasing capabilities and resources available on microcontrollers, there is a trend in the embedded industry to integrate multiple software functions on a single system to save cost, size, weight, and power. The integration raises new requirements, thereunder the need for spatial isolation, which is commonly established by using a memory protection unit (MPU) that can constrain access to the physical address space to a fixed set of address regions. MPU-based protection is limited in terms of available hardware, flexibility, granularity and ease of use. Software-based memory protection can provide an alternative or complement MPU-based protection, but has found little attention in the embedded domain. In this thesis, I evaluate qualitative and quantitative advantages and limitations of MPU-based memory protection and software-based protection based on a multi-JVM. I developed a framework composed of the AUTOSAR OS-like operating system CiAO and KESO, a Java implementation for deeply embedded systems. The framework allows choosing from no memory protection, MPU-based protection, software-based protection, and a combination of the two.
    [Show full text]
  • 45-Year CPU Evolution: One Law and Two Equations
    45-year CPU evolution: one law and two equations Daniel Etiemble LRI-CNRS University Paris Sud Orsay, France [email protected] Abstract— Moore’s law and two equations allow to explain the a) IC is the instruction count. main trends of CPU evolution since MOS technologies have been b) CPI is the clock cycles per instruction and IPC = 1/CPI is the used to implement microprocessors. Instruction count per clock cycle. c) Tc is the clock cycle time and F=1/Tc is the clock frequency. Keywords—Moore’s law, execution time, CM0S power dissipation. The Power dissipation of CMOS circuits is the second I. INTRODUCTION equation (2). CMOS power dissipation is decomposed into static and dynamic powers. For dynamic power, Vdd is the power A new era started when MOS technologies were used to supply, F is the clock frequency, ΣCi is the sum of gate and build microprocessors. After pMOS (Intel 4004 in 1971) and interconnection capacitances and α is the average percentage of nMOS (Intel 8080 in 1974), CMOS became quickly the leading switching capacitances: α is the activity factor of the overall technology, used by Intel since 1985 with 80386 CPU. circuit MOS technologies obey an empirical law, stated in 1965 and 2 Pd = Pdstatic + α x ΣCi x Vdd x F (2) known as Moore’s law: the number of transistors integrated on a chip doubles every N months. Fig. 1 presents the evolution for II. CONSEQUENCES OF MOORE LAW DRAM memories, processors (MPU) and three types of read- only memories [1]. The growth rate decreases with years, from A.
    [Show full text]
  • Using an MPU to Enforce Spatial Separation
    HighIntegritySystems Using an MPU to Enforce Spatial Separation Issue 1.3 - November 26, 2020 Copyright WITTENSTEIN aerospace & simulation ltd date as document, all rights reserved. WITTENSTEIN high integrity systems v Americas: +1 408 625 4712 ROTW: +44 1275 395 600 Email: [email protected] Web: www.highintegritysystems.com HighIntegritySystems Contents Contents..........................................................................................................................................2 List Of Figures.................................................................................................................................3 List Of Notation...............................................................................................................................3 CHAPTER 1 Introduction.....................................................................................................4 1.1 Introduction..............................................................................................................................4 1.2 Use Case - An Embedded System...........................................................................................5 CHAPTER 2 System Architecture and its Effect on Spatial Separation......................6 2.1 Spatial Separation with a Multi-Processor System....................................................................6 2.2 Spatial Separation with a Multi-Core System............................................................................6 2.3 Spatial Separation
    [Show full text]
  • Cuda C Best Practices Guide
    CUDA C BEST PRACTICES GUIDE DG-05603-001_v9.0 | June 2018 Design Guide TABLE OF CONTENTS Preface............................................................................................................ vii What Is This Document?..................................................................................... vii Who Should Read This Guide?...............................................................................vii Assess, Parallelize, Optimize, Deploy.....................................................................viii Assess........................................................................................................ viii Parallelize.................................................................................................... ix Optimize...................................................................................................... ix Deploy.........................................................................................................ix Recommendations and Best Practices.......................................................................x Chapter 1. Assessing Your Application.......................................................................1 Chapter 2. Heterogeneous Computing.......................................................................2 2.1. Differences between Host and Device................................................................ 2 2.2. What Runs on a CUDA-Enabled Device?...............................................................3 Chapter 3. Application Profiling.............................................................................
    [Show full text]
  • Strict Memory Protection for Microcontrollers
    Master Thesis Spring 2019 Strict Memory Protection for Microcontrollers Erlend Sveen Supervisor: Jingyue Li Co-supervisor: Magnus Själander Sunday 17th February, 2019 Abstract Modern desktop systems protect processes from each other with memory protection. Microcontroller systems, which lack support for memory virtualization, typically only uses memory protection for areas that the programmer deems necessary and does not separate processes completely. As a result the application still appears monolithic and only a handful of errors may be detected. This thesis presents a set of solutions for complete separation of processes, unleash- ing the full potential of the memory protection unit embedded in modern ARM-based microcontrollers. The operating system loads multiple programs from disk into indepen- dently protected portions of memory. These programs may then be started, stopped, modified, crashed etc. without affecting other running programs. When loading pro- grams, a new allocation algorithm is used that automatically aligns the memories for use with the protection hardware. A pager is written to satisfy additional run-time demands of applications, and communication primitives for inter-process communication is made available. Since every running process is unable to get access to other running processes, not only reliability but also security is improved. An application may be split so that unsafe or error-prone code is separated from mission-critical code, allowing it to be independently restarted when an error occurs. With executable and writeable memory access rights being mutually exclusive, code injection is made harder to perform. The solution is all transparent to the programmer. All that is required is to split an application into sub-programs that operates largely independently.
    [Show full text]
  • Memory Protection in Embedded Systems Lanfranco Lopriore Dipartimento Di Ingegneria Dell’Informazione, Università Di Pisa, Via G
    CORE Metadata, citation and similar papers at core.ac.uk Provided by Archivio della Ricerca - Università di Pisa Memory protection in embedded systems Lanfranco Lopriore Dipartimento di Ingegneria dell’Informazione, Università di Pisa, via G. Caruso 16, 56126 Pisa, Italy E-mail: [email protected] Abstract — With reference to an embedded system featuring no support for memory manage- ment, we present a model of a protection system based on passwords and keys. At the hardware level, our model takes advantage of a memory protection unit (MPU) interposed between the processor and the complex of the main memory and the input-output devices. The MPU sup- ports both concepts of a protection context and a protection domain. A protection context is a set of access rights for the memory pages; a protection domain is a set of one or more protection contexts. Passwords are associated with protection domains. A process that holds a key match- ing a given password can take advantage of this key to activate the corresponding domain. A small set of protection primitives makes it possible to modify the composition of the domains in a strictly controlled fashion. The proposed protection model is evaluated from a number of salient viewpoints, which include key distribution, review and revocation, the memory requirements for storage of the information concerning protection, and the time necessary for key validation. Keywords: access right; embedded system; protection; revocation. 1. INTRODUCTION We shall refer to a typical embedded system architecture featuring a microprocessor inter- facing both volatile and non-volatile primary memory devices, as well as a variety of input/out- put devices including sensors and actuators.
    [Show full text]
  • Multi-Cycle Datapathoperation
    Book's Definition of Performance • For some program running on machine X, PerformanceX = 1 / Execution timeX • "X is n times faster than Y" PerformanceX / PerformanceY = n • Problem: – machine A runs a program in 20 seconds – machine B runs the same program in 25 seconds 1 Example • Our favorite program runs in 10 seconds on computer A, which hasa 400 Mhz. clock. We are trying to help a computer designer build a new machine B, that will run this program in 6 seconds. The designer can use new (or perhaps more expensive) technology to substantially increase the clock rate, but has informed us that this increase will affect the rest of the CPU design, causing machine B to require 1.2 times as many clockcycles as machine A for the same program. What clock rate should we tellthe designer to target?" • Don't Panic, can easily work this out from basic principles 2 Now that we understand cycles • A given program will require – some number of instructions (machine instructions) – some number of cycles – some number of seconds • We have a vocabulary that relates these quantities: – cycle time (seconds per cycle) – clock rate (cycles per second) – CPI (cycles per instruction) a floating point intensive application might have a higher CPI – MIPS (millions of instructions per second) this would be higher for a program using simple instructions 3 Performance • Performance is determined by execution time • Do any of the other variables equal performance? – # of cycles to execute program? – # of instructions in program? – # of cycles per second? – average # of cycles per instruction? – average # of instructions per second? • Common pitfall: thinking one of the variables is indicative of performance when it really isn’t.
    [Show full text]
  • CS2504: Computer Organization
    CS2504, Spring'2007 ©Dimitris Nikolopoulos CS2504: Computer Organization Lecture 4: Evaluating Performance Instructor: Dimitris Nikolopoulos Guest Lecturer: Matthew Curtis-Maury CS2504, Spring'2007 ©Dimitris Nikolopoulos Understanding Performance Why do we study performance? Evaluate during design Evaluate before purchasing Key to understanding underlying organizational motivation How can we (meaningfully) compare two machines? Performance, Cost, Value, etc Main issue: Need to understand what factors in the architecture contribute to overall system performance and the relative importance of these factors Effects of ISA on performance 2 How will hardware change affect performance CS2504, Spring'2007 ©Dimitris Nikolopoulos Airplane Performance Analogy Airplane Passengers Range Speed Boeing 777 375 4630 610 Boeing 747 470 4150 610 Concorde 132 4000 1250 Douglas DC-8-50 146 8720 544 Fighter Jet 4 2000 1500 What metric do we use? Concorde is 2.05 times faster than the 747 747 has 1.74 times higher throughput What about cost? And the winner is: It Depends! 3 CS2504, Spring'2007 ©Dimitris Nikolopoulos Throughput vs. Response Time Response Time: Execution time (e.g. seconds or clock ticks) How long does the program take to execute? How long do I have to wait for a result? Throughput: Rate of completion (e.g. results per second/tick) What is the average execution time of the program? Measure of total work done Upgrading to a newer processor will improve: response time Adding processors to the system will improve: throughput 4 CS2504, Spring'2007 ©Dimitris Nikolopoulos Example: Throughput vs. Response Time Suppose we know that an application that uses both a desktop client and a remote server is limited by network performance.
    [Show full text]
  • Analysis of Body Bias Control Using Overhead Conditions for Real Time Systems: a Practical Approach∗
    IEICE TRANS. INF. & SYST., VOL.E101–D, NO.4 APRIL 2018 1116 PAPER Analysis of Body Bias Control Using Overhead Conditions for Real Time Systems: A Practical Approach∗ Carlos Cesar CORTES TORRES†a), Nonmember, Hayate OKUHARA†, Student Member, Nobuyuki YAMASAKI†, Member, and Hideharu AMANO†, Fellow SUMMARY In the past decade, real-time systems (RTSs), which must in RTSs. These techniques can improve energy efficiency; maintain time constraints to avoid catastrophic consequences, have been however, they often require a large amount of power since widely introduced into various embedded systems and Internet of Things they must control the supply voltages of the systems. (IoTs). The RTSs are required to be energy efficient as they are used in embedded devices in which battery life is important. In this study, we in- Body bias (BB) control is another solution that can im- vestigated the RTS energy efficiency by analyzing the ability of body bias prove RTS energy efficiency as it can manage the tradeoff (BB) in providing a satisfying tradeoff between performance and energy. between power leakage and performance without affecting We propose a practical and realistic model that includes the BB energy and the power supply [4], [5].Itseffect is further endorsed when timing overhead in addition to idle region analysis. This study was con- ducted using accurate parameters extracted from a real chip using silicon systems are enabled with silicon on thin box (SOTB) tech- on thin box (SOTB) technology. By using the BB control based on the nology [6], which is a novel and advanced fully depleted sili- proposed model, about 34% energy reduction was achieved.
    [Show full text]
  • A Performance Analysis Tool for Intel SGX Enclaves
    sgx-perf: A Performance Analysis Tool for Intel SGX Enclaves Nico Weichbrodt Pierre-Louis Aublin Rüdiger Kapitza IBR, TU Braunschweig LSDS, Imperial College London IBR, TU Braunschweig Germany United Kingdom Germany [email protected] [email protected] [email protected] ABSTRACT the provider or need to refrain from offloading their workloads Novel trusted execution technologies such as Intel’s Software Guard to the cloud. With the advent of Intel’s Software Guard Exten- Extensions (SGX) are considered a cure to many security risks in sions (SGX)[14, 28], the situation is about to change as this novel clouds. This is achieved by offering trusted execution contexts, so trusted execution technology enables confidentiality and integrity called enclaves, that enable confidentiality and integrity protection protection of code and data – even from privileged software and of code and data even from privileged software and physical attacks. physical attacks. Accordingly, researchers from academia and in- To utilise this new abstraction, Intel offers a dedicated Software dustry alike recently published research works in rapid succession Development Kit (SDK). While it is already used to build numerous to secure applications in clouds [2, 5, 33], enable secure network- applications, understanding the performance implications of SGX ing [9, 11, 34, 39] and fortify local applications [22, 23, 35]. and the offered programming support is still in its infancy. This Core to all these works is the use of SGX provided enclaves, inevitably leads to time-consuming trial-and-error testing and poses which build small, isolated application compartments designed to the risk of poor performance.
    [Show full text]
  • ESC-470: ARM 9 Instruction Set Architecture with Performance
    ARM 9 Instruction Set Architecture Introduction with Performance Perspective Joe-Ming Cheng, Ph.D. ARM-family processors are positioned among the leaders in key embedded applications. Many presentations and short lectures have already addressed the ARM’s applications and capabilities. In this introduction, we intend to discuss the ARM’s instruction set uniqueness from the performance prospective. This introduction is also trying to follow the approaches established by two outstanding textbooks of David Patterson and John Hennessey [PetHen00] [HenPet02]. 1.0 ARM Instruction Set Architecture Processor instruction set architecture (ISA) choices have evolved from accumulator, stack, register-to- memory, to register-register (load-store) organization. ARM 9 ISA is a load-store machine. ARM 9 ISA takes advantage of its smaller set of registers (16 vs. many 32-register processors) to incorporate more direct controls and achieve high encoding density. ARM’s load or store multiple register instruction, for example , allows enlisting of all possible registers and conditional execution in one instruction. The Thumb mode instruction set is another exa mple of how ARM ISA facilitates higher encode density. Rather than compressing the code, Thumb -mode instructions are two 16-bit instructions packed in a 32-bit ARM-mode instruction space. The Thumb -mode instructions are a subset of ARM instructions. When executing in Thumb mode, a single 32-bit instruction fetch cycle effectively brings in two instructions. Thumb code reduces access bandwidth, code size, and improves instruction cache hit rate. Another way ARM achieves cycle time reduction is by using Harvard architecture. The architecture facilitates independent data and instruction buses.
    [Show full text]
  • Introduction to Uclinux
    Introduction to uClinux V M Introduction to uClinux Michael Opdenacker Free Electrons http://free-electrons.com Created with OpenOffice.org 2.x Thanks to Nicolas Rougier (Copyright 2003, http://webloria.loria.fr/~rougier/) for the Tux image Introduction to uClinux © Copyright 2004-2007, Free Electrons Creative Commons Attribution-ShareAlike 2.5 license http://free-electrons.com Nov 20, 2007 1 Rights to copy Attribution ± ShareAlike 2.5 © Copyright 2004-2007 You are free Free Electrons to copy, distribute, display, and perform the work [email protected] to make derivative works to make commercial use of the work Document sources, updates and translations: Under the following conditions http://free-electrons.com/articles/uclinux Attribution. You must give the original author credit. Corrections, suggestions, contributions and Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license translations are welcome! identical to this one. For any reuse or distribution, you must make clear to others the license terms of this work. Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. License text: http://creativecommons.org/licenses/by-sa/2.5/legalcode Introduction to uClinux © Copyright 2004-2007, Free Electrons Creative Commons Attribution-ShareAlike 2.5 license http://free-electrons.com Nov 20, 2007 2 Best viewed with... This document is best viewed with a recent PDF reader or with OpenOffice.org itself! Take advantage of internal or external hyperlinks. So, don't hesitate to click on them! Find pages quickly thanks to automatic search.
    [Show full text]