Proceedings of the 10 USENIX Security Symposium

Total Page:16

File Type:pdf, Size:1020Kb

Proceedings of the 10 USENIX Security Symposium USENIX Association Proceedings of the 10th USENIX Security Symposium Washington, D.C., USA August 13–17, 2001 THE ADVANCED COMPUTING SYSTEMS ASSOCIATION © 2001 by The USENIX Association All Rights Reserved For more information about the USENIX Association: Phone: 1 510 528 8649 FAX: 1 510 548 5738 Email: [email protected] WWW: http://www.usenix.org Rights to individual papers remain with the author or the author's employer. Permission is granted for noncommercial reproduction of the work for educational or research purposes. This copyright notice must be included in the reproduced paper. USENIX acknowledges all trademarks herein. RaceGuard: Kernel Protection From Temporary File Race Vulnerabilities Crispin Cowan, Steve Beattie, Chris Wright, and Greg Kroah-Hartman WireX Communications, Inc. http://wirex.com/ Abstract This race condition becomes a security vulnerability if the victim program creating the temporary file is privi- Temporary file race vulnerabilities occur when privi- leged (i.e. running as root or some other privileged leged programs attempt to create temporary files in an user-ID) and the attacker creates a link pointing to a unsafe manner. “Unsafe” means “non-atomic with security sensitive file such as /etc/passwd or respect to an attacker’s activities.” There is no portable /etc/hosts.allow. When this occurs, the standard for safely (atomically) creating temporary files, open(O_CREAT) will obliterate the data contained in and many operating systems have no safe temporary file the sensitive file. The fopen() library function, being creation at all. As a result, many programs continue to a wrapper around open(O_CREAT), is similarly vul- use unsafe means to create temporary files, resulting in nerable. widespread vulnerabilities. This paper presents Race- Guard: a kernel enhancement that detects attempts to There are two commonly accepted mechanisms that exploit temporary file race vulnerabilities, and does so exist to prevent this race condition: using open() with with sufficient speed and precision that the attack can be the O_CREAT and O_EXCL flags, or using the halted before it takes effect. RaceGuard has been imple- mkstemp() library function (which is a wrapper mented, tested, and measured. We show that RaceGuard around open(O_CREAT|O_EXCL)). When is effective at stopping temporary file race attacks, pre- open(O_CREAT|O_EXCL) is called on a file that serves compatibility (no legitimate software is broken), already exists, it will fail and prevent the race attack. and preserves performance (overhead is minimal). Unfortunately, because these mechanisms are not ubiq- uitously available and portable, common programs 1 Introduction (such as Apache [3, 13]) still continue to use Attacks exploiting concurrency problems (“race vulner- mktemp() and friends, despite the fact that the Linux abilities”) are nearly as old as the study of computer sys- mktemp man page says “Never use mktemp().” tem security [1, 5]. These are called TOCTTOU (“Time of Check To Time Of Use”) errors [6]. Of particular This paper presents RaceGuard: a kernel enhancement interest is the temporary file creation vulnerability: pro- that detects attempts to exploit temporary file race vul- grams seeking to create a temporary file first check to nerabilities, and does so with sufficient speed and preci- see if a candidate file name exists, and then proceed to sion that the attack can be halted before it takes effect. create that file. The problem occurs if the attacker can RaceGuard functions by detecting the change in circum- race in between the file existence check and the file cre- stances between the stat() call and the open() call. If the ation, and the attacker creates the file that the victim stat() “fails” (the file does not exist), then RaceGuard program expected to create. caches the file name. If a subsequent open() call pro- vides the same name, and discovers that the file does In concrete terms, this problem occurs on UNIX systems exist, then RaceGuard detects a race attack, and aborts when programs use stat() or lstat() to probe for the open() operation. the existence of files, and open(O_CREAT) to create the files. An encapsulated means to create temporary The rest of this paper is organized as follows.Section 2 names is the mktemp() library function.1 The elaborates on the temporary file vulnerability issue. Sec- mktemp() library function simply encapsulates the tion 3 presents the RaceGuard design and implementa- lstat() call, and thus mktemp() followed by tion. Section 4 presents our security testing against open(O_CREAT) is vulnerable to race attacks. known race vulnerabilities in actively used software. Section 5 presents our compatibility testing, showing that RaceGuard protection does not interfere with nor- mal system operations. Section 6 presents our perfor- 1. and related library functions tmpnam() and tempnam(). mance testing, showing that the performance costs of This work supported in part by DARPA contract N66001-00-C-8032. RaceGuard protection are minimal. Section 7 describes Guard algorithm. Section 3.2 describes the RaceGuard related work in defending against temporary file race implementation and the cache management policy. vulnerabilities. Section 8 presents our conclusions. 3.1 RaceGuard Design 2 Temporary File Race Vulnerabilities RaceGuard seeks to detect pertinent changes in the file The basic form of a temporary file race vulnerability is system between the time an application probes for a that a privileged program first probes the state of the file nominated temporary file name, and the time the file is system, and then based on the results of that probe, takes actually created. “Pertinent” means changes with some action. The attacker can exploit the vulnerability respect to the nominated name. The RaceGuard algo- by “racing” between the probe and the action to change rithm to achieve this is as follows: the state of the file system in some critical way, such that the victim program’s action will have an unintended • Each process keeps a cache of potential temporary effect. file races. This cache is a list of file names, associ- ated with each process control block within the ker- The simple form of this attack is temporary file creation. nel. The victim program seeks to create a temporary file, • If file probe result is “non-existent file,” then cache probes for the existence of the file, and if the nominated the file name in the process’s RaceGuard cache. file name is not found, proceeds to create the file. The • If file creation hits a file that already exists, and the attacker exploits this by creating either a symbolic link name matches a name in the RaceGuard cache, then that matches the name of the file about to be created, this is a race attack: abort the open attempt. and points to a security sensitive file. The result is that • If file creation succeeds without conflicts, and the victim program will unwittingly over-write the secu- matches a name in the RaceGuard cache, then clear rity sensitive file with unintended content. that entry from the cache. This prevents “false posi- tive” RaceGuard events when a program uses the A variation on this scheme is the “dangling symlink”. same name for a file more than once. The victim program performs the same sequence as This caching mechanism serves to detect and differenti- above. The attacking program races in and creates a ate between the sequence “probe; create”, and “probe; symlink or hard link from the matching name to a non- attacker meddling; create”. To defend against the “dan- existent file whose existence has security implications, gling symlink” variant attack described in Section 2, such as /etc/hosts.allow or /etc/nologin. RaceGuard does two resolves on the name provided to open that are in the RaceGuard cache: the first follows Another variation is the “file swap.” Here the victim symlinks, while the second does not. If the two resolve program is a SUID root program that can be asked to differently, and the argument name matches an entry in write to a specific file [6]. The victim program defen- the RaceGuard cache, then this is treated as a race sively checks to see if the requesting user has access to attack. the file, and then only does the write if the user has per- mission. The attacker provides a file that they have RaceGuard does not defend against the “file swap” access, to, and between the access check and the write attack. Because the attack concerns an already existent operation, the attacker swaps the file for a symlink file, this is not really a temporary file race attack. In pointing to a security sensitive file. practice, such vulnerabilities appear to be relatively rare: searching Securityfocus.com’s vulnerability data- 3 RaceGuard: Dynamic Protection from base [18] for “race” produced 75 hits, while searching Race Attacks for “race & !tmp & !temp” produced only 24 hits. Even among the 24, random sampling indicates that many of RaceGuard detects attempts to exploit race vulnerabili- them are actually temporary file issues, but did not say ties at run time by detecting a change in the environment so in the name of the vulnerability. between the time the program probes for the existence of a file, and the time it tries to create it: if the file 3.2 RaceGuard Implementation & Cache named “foo” does not exist at the time of the stat, but does exist at the time of the open, then someone tried to Management Policy race us, so abort the operation. RaceGuard achieves this The RaceGuard implementation is in the kernel, facili- by caching the file names that are probed, and when cre- tating both per-process and inter-process RaceGuard ation attempts occur that hit existing files, the names are cache management. RaceGuard mediates three basic compared to the cache. Section 3.1 describes the Race- types of system calls: • those which can inform the program that a file sys- 3.
Recommended publications
  • Version 7.8-Systemd
    Linux From Scratch Version 7.8-systemd Created by Gerard Beekmans Edited by Douglas R. Reno Linux From Scratch: Version 7.8-systemd by Created by Gerard Beekmans and Edited by Douglas R. Reno Copyright © 1999-2015 Gerard Beekmans Copyright © 1999-2015, Gerard Beekmans All rights reserved. This book is licensed under a Creative Commons License. Computer instructions may be extracted from the book under the MIT License. Linux® is a registered trademark of Linus Torvalds. Linux From Scratch - Version 7.8-systemd Table of Contents Preface .......................................................................................................................................................................... vii i. Foreword ............................................................................................................................................................. vii ii. Audience ............................................................................................................................................................ vii iii. LFS Target Architectures ................................................................................................................................ viii iv. LFS and Standards ............................................................................................................................................ ix v. Rationale for Packages in the Book .................................................................................................................... x vi. Prerequisites
    [Show full text]
  • Powerview Command Reference
    PowerView Command Reference TRACE32 Online Help TRACE32 Directory TRACE32 Index TRACE32 Documents ...................................................................................................................... PowerView User Interface ............................................................................................................ PowerView Command Reference .............................................................................................1 History ...................................................................................................................................... 12 ABORT ...................................................................................................................................... 13 ABORT Abort driver program 13 AREA ........................................................................................................................................ 14 AREA Message windows 14 AREA.CLEAR Clear area 15 AREA.CLOSE Close output file 15 AREA.Create Create or modify message area 16 AREA.Delete Delete message area 17 AREA.List Display a detailed list off all message areas 18 AREA.OPEN Open output file 20 AREA.PIPE Redirect area to stdout 21 AREA.RESet Reset areas 21 AREA.SAVE Save AREA window contents to file 21 AREA.Select Select area 22 AREA.STDERR Redirect area to stderr 23 AREA.STDOUT Redirect area to stdout 23 AREA.view Display message area in AREA window 24 AutoSTOre ..............................................................................................................................
    [Show full text]
  • Rhd256.Bowez Notes.2006-07-20.Txt Thu Jul 20 15:31
    ../rhd256.bowez_notes.2006-07-20.txt Thu Jul 20 15:31:29 2006 1 ==> ./01_intro/notes.txt <== ---------------------------------------------------------------------- ---------------------------------------------------------------------- 2.3 Bash Special Characaters 1.3 Prerequisates ---------------------------------------------------------------------- ---------------------------------------------------------------------- ------------------------------------------------------------------ Familiarity: Redirection (Stream Manipulation) ------------------------------------------------------------------ the classroom setup (server1, station1, etc...) the "pub" directory every process has three default file descriptors (streams): Common Tools: 0: stdin 1: stdout terminal: 2: stderr changing fonts, etc.... - by default, all are connected to the terminal. editors: - In RHL, can be accessed by /dev/std{in,out,err} emacs vi, vim, gvim < redirect descriptor input pico -w, gedit > redirect descriptor output (create or clobber) (less pager) >> redirect descriptor output (create or append) finding information: 2>&1 bind one descriptor to another (i.e., combine stderr and stdout) --help, -h >& bash shortcut for the same man pages (chapters) info pages (info, pinfo, nautilus) examples: /usr/share/doc grep root /etc/* rpm (-qf filename, -ql, -qi) grep root /etc/* > /tmp/out grep root /etc/* 2> /tmp/err ---------------------------------------------------------------------- grep root /etc/* > /tmp/out2 2> /tmp/err2 grep root /etc/* >& /tmp/all 1.4 Procedures
    [Show full text]
  • Computer Security 03
    Computer Security 03. Program Hijacking & Code Injection Paul Krzyzanowski Rutgers University Spring 2019 September 25, 2019 CS 419 © 2019 Paul Krzyzanowski 1 Top vulnerability concerns for 2019 MITRE, a non-profit organization that manages federally-funded research & development centers, publishes a list of top security weaknesses Rank Name Score 1 Improper Restriction of Operations within the Bounds of a Memory Buffer 75.56 2 Cross-site Scripting 45.69 3 Improper Input Validation 43.61 4 Information Exposure 32.12 5 Out-of-bounds Read 26.53 6 SQL Injection 24.54 7 Use After Free 17.94 8 Integer Overflow or Wraparound 17.35 9 Cross-Site Request Forgery (CSRF) 15.54 10 14.10 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') https://cwe.mitre.org/top25/archive/2019/2019_cwe_top25.html September 25, 2019 CS 419 © 2019 Paul Krzyzanowski 2 Hijacking Getting software to do something different from what the user or developer expected Examples: • Redirect web browser to a malicious site • Change DNS (IP address lookup) results • Change search engine • Change search paths to load different libraries or have different programs run • Intercept & alter messages Code injection Getting a program to process data in a way that it changes the execution of a program September 25, 2019 CS 419 © 2019 Paul Krzyzanowski 3 Bugs and mistakes • Most attacks are due to – Social engineering: getting a legitimate user to do something – Or bugs: using a program in a way it was not intended • Attacked system may be further weakened because
    [Show full text]
  • 11.6. Tempfile — Generate Temporary Files and Directories — Python V2
    Navigation • index • modules | • next | • previous | • Python v2.6.4 documentation » • The Python Standard Library » • 11. File and Directory Access » 11.6. tempfile — Generate temporary files and directories¶ This module generates temporary files and directories. It works on all supported platforms. In version 2.3 of Python, this module was overhauled for enhanced security. It now provides three new functions, NamedTemporaryFile(), mkstemp(), and mkdtemp(), which should eliminate all remaining need to use the insecure mktemp() function. Temporary file names created by this module no longer contain the process ID; instead a string of six random characters is used. Also, all the user-callable functions now take additional arguments which allow direct control over the location and name of temporary files. It is no longer necessary to use the global tempdir and template variables. To maintain backward compatibility, the argument order is somewhat odd; it is recommended to use keyword arguments for clarity. The module defines the following user-callable functions: tempfile.TemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]])¶ Return a file-like object that can be used as a temporary storage area. The file is created using mkstemp(). It will be destroyed as soon as it is closed (including an implicit close when the object is garbage collected). Under Unix, the directory entry for the file is removed immediately after the file is created. Other platforms do not support this; your code should not rely on a temporary file created using this function having or not having a visible name in the file system. The mode parameter defaults to 'w+b' so that the file created can be read and written without being closed.
    [Show full text]
  • GNU Coreutils Cheat Sheet (V1.00) Created by Peteris Krumins ([email protected], -- Good Coders Code, Great Coders Reuse)
    GNU Coreutils Cheat Sheet (v1.00) Created by Peteris Krumins ([email protected], www.catonmat.net -- good coders code, great coders reuse) Utility Description Utility Description arch Print machine hardware name nproc Print the number of processors base64 Base64 encode/decode strings or files od Dump files in octal and other formats basename Strip directory and suffix from file names paste Merge lines of files cat Concatenate files and print on the standard output pathchk Check whether file names are valid or portable chcon Change SELinux context of file pinky Lightweight finger chgrp Change group ownership of files pr Convert text files for printing chmod Change permission modes of files printenv Print all or part of environment chown Change user and group ownership of files printf Format and print data chroot Run command or shell with special root directory ptx Permuted index for GNU, with keywords in their context cksum Print CRC checksum and byte counts pwd Print current directory comm Compare two sorted files line by line readlink Display value of a symbolic link cp Copy files realpath Print the resolved file name csplit Split a file into context-determined pieces rm Delete files cut Remove parts of lines of files rmdir Remove directories date Print or set the system date and time runcon Run command with specified security context dd Convert a file while copying it seq Print sequence of numbers to standard output df Summarize free disk space setuidgid Run a command with the UID and GID of a specified user dir Briefly list directory
    [Show full text]
  • Constraints in Dynamic Symbolic Execution: Bitvectors Or Integers?
    Constraints in Dynamic Symbolic Execution: Bitvectors or Integers? Timotej Kapus, Martin Nowack, and Cristian Cadar Imperial College London, UK ft.kapus,m.nowack,[email protected] Abstract. Dynamic symbolic execution is a technique that analyses programs by gathering mathematical constraints along execution paths. To achieve bit-level precision, one must use the theory of bitvectors. However, other theories might achieve higher performance, justifying in some cases the possible loss of precision. In this paper, we explore the impact of using the theory of integers on the precision and performance of dynamic symbolic execution of C programs. In particular, we compare an implementation of the symbolic executor KLEE using a partial solver based on the theory of integers, with a standard implementation of KLEE using a solver based on the theory of bitvectors, both employing the popular SMT solver Z3. To our surprise, our evaluation on a synthetic sort benchmark, the ECA set of Test-Comp 2019 benchmarks, and GNU Coreutils revealed that for most applications the integer solver did not lead to any loss of precision, but the overall performance difference was rarely significant. 1 Introduction Dynamic symbolic execution is a popular program analysis technique that aims to systematically explore all the paths in a program. It has been very successful in bug finding and test case generation [3, 4]. The research community and industry have produced many tools performing symbolic execution, such as CREST [5], FuzzBALL [9], KLEE [2], PEX [14], and SAGE [6], among others. To illustrate how dynamic symbolic execution works, consider the program shown in Figure 1a.
    [Show full text]
  • NSWI 0138: Advanced Unix Programming
    NSWI 0138: Advanced Unix programming (c) 2011-2016 Vladim´ırKotal (c) 2009-2010 Jan Pechanec, Vladim´ırKotal SISAL MFF UK, Malostransk´en´am.25, 118 00 Praha 1 Charles University Czech Republic Vladim´ırKotal [email protected] March 10, 2016 1 Vladim´ırKotal NSWI 0138 (Advanced Unix programming) Contents 1 Overview 5 1.1 What is this lecture about? . .5 1.2 The lecture will cover... .5 1.3 A few notes on source code files . .6 2 Testing 6 2.1 Why?...........................................6 2.2 When ? . .6 2.3 Types of testing . .7 3 Debugging 8 3.1 Debuging in general . .8 3.2 Observing . .9 3.3 Helper tools . .9 3.3.1 ctags . .9 3.3.2 cscope . 10 3.3.3 OpenGrok . 11 3.3.4 Other tools . 11 3.4 Debugging data . 11 3.4.1 stabs . 11 3.4.2 DWARF . 12 3.4.3 CTF (Compact C Type Format) . 12 3.5 Resource leaks . 13 3.6 libumem . 13 3.6.1 How does libumem work . 14 3.6.2 Using libumem+mdb to find memory leaks . 14 3.6.3 How does ::findleaks work . 16 3.7 watchmalloc . 17 3.8 Call tracing . 18 3.9 Using /proc . 19 3.10 Debugging dynamic libraries . 20 3.11 Debuggers . 20 3.12 Symbol search and interposition . 20 3.13 dtrace . 21 4 Terminals 21 4.1 Terminal I/O Overview . 21 4.2 Terminal I/O Overview (cont.) . 22 4.3 Physical (Hardware) Terminal . 24 4.4 stty(1) command . 24 4.5 TTY Driver Connected To a Phy Terminal .
    [Show full text]
  • Advanced Bash-Scripting Guide
    Advanced Bash−Scripting Guide An in−depth exploration of the art of shell scripting Mendel Cooper <[email protected]> 5.0 24 June 2007 Revision History Revision 4.2 10 Dec 2006 Revised by: mc 'SPARKLEBERRY' release: Important Update. Revision 4.3 29 Apr 2007 Revised by: mc 'INKBERRY' release: Minor Update. Revision 5.0 24 Jun 2007 Revised by: mc 'SERVICEBERRY' release: Major Update. This tutorial assumes no previous knowledge of scripting or programming, but progresses rapidly toward an intermediate/advanced level of instruction . all the while sneaking in little snippets of UNIX® wisdom and lore. It serves as a textbook, a manual for self−study, and a reference and source of knowledge on shell scripting techniques. The exercises and heavily−commented examples invite active reader participation, under the premise that the only way to really learn scripting is to write scripts. This book is suitable for classroom use as a general introduction to programming concepts. The latest update of this document, as an archived, bzip2−ed "tarball" including both the SGML source and rendered HTML, may be downloaded from the author's home site. A pdf version is also available ( pdf mirror site). See the change log for a revision history. Dedication For Anita, the source of all the magic Advanced Bash−Scripting Guide Table of Contents Chapter 1. Why Shell Programming?...............................................................................................................1 Chapter 2. Starting Off With a Sha−Bang.......................................................................................................3
    [Show full text]
  • GPL-3-Free Replacements of Coreutils 1 Contents
    GPL-3-free replacements of coreutils 1 Contents 2 Coreutils GPLv2 2 3 Alternatives 3 4 uutils-coreutils ............................... 3 5 BSDutils ................................... 4 6 Busybox ................................... 5 7 Nbase .................................... 5 8 FreeBSD ................................... 6 9 Sbase and Ubase .............................. 6 10 Heirloom .................................. 7 11 Replacement: uutils-coreutils 7 12 Testing 9 13 Initial test and results 9 14 Migration 10 15 Due to the nature of Apertis and its target markets there are licensing terms that 1 16 are problematic and that forces the project to look for alternatives packages. 17 The coreutils package is good example of this situation as its license changed 18 to GPLv3 and as result Apertis cannot provide it in the target repositories and 19 images. The current solution of shipping an old version which precedes the 20 license change is not tenable in the long term, as there are no upgrades with 21 bugfixes or new features for such important package. 22 This situation leads to the search for a drop-in replacement of coreutils, which 23 need to provide compatibility with the standard GNU coreutils packages. The 24 reason behind is that many other packages rely on the tools it provides, and 25 failing to do that would lead to hard to debug failures and many custom patches 26 spread all over the archive. In this regard the strict requirement is to support 27 the features needed to boot a target image with ideally no changes in other 28 components. The features currently available in our coreutils-gplv2 fork are a 29 good approximation. 30 Besides these specific requirements, the are general ones common to any Open 31 Source Project, such as maturity and reliability.
    [Show full text]
  • Learning Embedded Linux Through the File System: a Top-Down Approach
    Learning embedded Linux through the file system: A top-down approach Jason Kridner, [email protected] June 8, 2011, 10:10AM ESC Chicago room 34 http://beagleboard.org/linux_education Abstract Typical introductions to embedded Linux focus on complex tasks, like building device drivers, that are highly desired by at least some people working on your Linux product team. What about the rest of us that simply want to build a quick understanding of how to do some of the simple tasks that are trivial in microcontrollers without using operating systems, like accessing GPIO pins and performing I2C or SPI serial communications? This class takes a quick tops-down overview from the perspective of an electrical engineer looking to take advantage of the latest in GUI building technologies, like Android, Qt, and HTML5, without completely losing access to the underlying hardware for simple system integration tasks. Getting started Much to learn ◦ I‟m used to microcontrollers: just give me the datasheet with register definitions and set me free! Training on boot & device drivers useful ◦ Often geared more at system bring-up ◦ What about the everyday user? ◦ Where is that abstraction benefit? Let‟s just walk a working system Kernel.org documentation http://www.kernel.org/doc/ Documentation extracted from the Linux kernel and mirrored on the web where Google can find it: ◦ Documentation - Text files in the kernel source tarball's Documentation subdirectory. ◦ htmldocs - Kernel Documentation maintained in docbook format (output of "make htmldocs"). ◦ Menuconfig - help text for each kernel configuration option (from kconfig source). ◦ README various README files scattered around Linux kernel source ◦ RFC - List of IETF RFCs referred to by kernel source files.
    [Show full text]
  • GNU Coreutils Core GNU Utilities for Version 9.0, 20 September 2021
    GNU Coreutils Core GNU utilities for version 9.0, 20 September 2021 David MacKenzie et al. This manual documents version 9.0 of the GNU core utilities, including the standard pro- grams for text and file manipulation. Copyright c 1994{2021 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled \GNU Free Documentation License". i Short Contents 1 Introduction :::::::::::::::::::::::::::::::::::::::::: 1 2 Common options :::::::::::::::::::::::::::::::::::::: 2 3 Output of entire files :::::::::::::::::::::::::::::::::: 12 4 Formatting file contents ::::::::::::::::::::::::::::::: 22 5 Output of parts of files :::::::::::::::::::::::::::::::: 29 6 Summarizing files :::::::::::::::::::::::::::::::::::: 41 7 Operating on sorted files ::::::::::::::::::::::::::::::: 47 8 Operating on fields ::::::::::::::::::::::::::::::::::: 70 9 Operating on characters ::::::::::::::::::::::::::::::: 80 10 Directory listing:::::::::::::::::::::::::::::::::::::: 87 11 Basic operations::::::::::::::::::::::::::::::::::::: 102 12 Special file types :::::::::::::::::::::::::::::::::::: 125 13 Changing file attributes::::::::::::::::::::::::::::::: 135 14 File space usage ::::::::::::::::::::::::::::::::::::: 143 15 Printing text :::::::::::::::::::::::::::::::::::::::
    [Show full text]