aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/books/developers-handbook/secure/_index.po
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/content/en/books/developers-handbook/secure/_index.po')
-rw-r--r--documentation/content/en/books/developers-handbook/secure/_index.po624
1 files changed, 624 insertions, 0 deletions
diff --git a/documentation/content/en/books/developers-handbook/secure/_index.po b/documentation/content/en/books/developers-handbook/secure/_index.po
new file mode 100644
index 0000000000..c298451c7b
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/secure/_index.po
@@ -0,0 +1,624 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 10:28-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:1
+#, no-wrap
+msgid "Secure Programming in FreeBSD"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:1
+#, no-wrap
+msgid "Chapter 3. Secure Programming"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:15
+#, no-wrap
+msgid "Secure Programming"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:53
+#, no-wrap
+msgid "Synopsis"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:56
+msgid ""
+"This chapter describes some of the security issues that have plagued UNIX(R) "
+"programmers for decades and some of the new tools available to help "
+"programmers avoid writing exploitable code."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:58
+#, no-wrap
+msgid "Secure Design Methodology"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:63
+msgid ""
+"Writing secure applications takes a very scrutinous and pessimistic outlook "
+"on life. Applications should be run with the principle of \"least privilege"
+"\" so that no process is ever running with more than the bare minimum access "
+"that it needs to accomplish its function. Previously tested code should be "
+"reused whenever possible to avoid common mistakes that others may have "
+"already fixed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:67
+msgid ""
+"One of the pitfalls of the UNIX(R) environment is how easy it is to make "
+"assumptions about the sanity of the environment. Applications should never "
+"trust user input (in all its forms), system resources, inter-process "
+"communication, or the timing of events. UNIX(R) processes do not execute "
+"synchronously so logical operations are rarely atomic."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:69
+#, no-wrap
+msgid "Buffer Overflows"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:75
+msgid ""
+"Buffer Overflows have been around since the very beginnings of the von "
+"Neumann crossref:bibliography[cod,1] architecture. They first gained "
+"widespread notoriety in 1988 with the Morris Internet worm. Unfortunately, "
+"the same basic attack remains effective today. By far the most common type "
+"of buffer overflow attack is based on corrupting the stack."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:84
+msgid ""
+"Most modern computer systems use a stack to pass arguments to procedures and "
+"to store local variables. A stack is a last in first out (LIFO) buffer in "
+"the high memory area of a process image. When a program invokes a function "
+"a new \"stack frame\" is created. This stack frame consists of the "
+"arguments passed to the function as well as a dynamic amount of local "
+"variable space. The \"stack pointer\" is a register that holds the current "
+"location of the top of the stack. Since this value is constantly changing "
+"as new values are pushed onto the top of the stack, many implementations "
+"also provide a \"frame pointer\" that is located near the beginning of a "
+"stack frame so that local variables can more easily be addressed relative to "
+"this value. crossref:bibliography[cod,1] The return address for function "
+"calls is also stored on the stack, and this is the cause of stack-overflow "
+"exploits since overflowing a local variable in a function can overwrite the "
+"return address of that function, potentially allowing a malicious user to "
+"execute any code he or she wants."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:87
+msgid ""
+"Although stack-based attacks are by far the most common, it would also be "
+"possible to overrun the stack with a heap-based (malloc/free) attack."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:90
+msgid ""
+"The C programming language does not perform automatic bounds checking on "
+"arrays or pointers as many other languages do. In addition, the standard C "
+"library is filled with a handful of very dangerous functions."
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:96
+#, no-wrap
+msgid "`strcpy`(char *dest, const char *src)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:100
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:105
+#, no-wrap
+msgid "May overflow the dest buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:101
+#, no-wrap
+msgid "`strcat`(char *dest, const char *src)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:106
+#, no-wrap
+msgid "`getwd`(char *buf)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:110
+#, no-wrap
+msgid "May overflow the buf buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:111
+#, no-wrap
+msgid "`gets`(char *s)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:115
+#, no-wrap
+msgid "May overflow the s buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:116
+#, no-wrap
+msgid "`[vf]scanf`(const char *format, ...)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:120
+#, no-wrap
+msgid "May overflow its arguments."
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:121
+#, no-wrap
+msgid "`realpath`(char *path, char resolved_path[])"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:125
+#, no-wrap
+msgid "May overflow the path buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:126
+#, no-wrap
+msgid "`[v]sprintf`(char *str, const char *format, ...)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:129
+#, no-wrap
+msgid "May overflow the str buffer."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:131
+#, no-wrap
+msgid "Example Buffer Overflow"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:134
+msgid ""
+"The following example code contains a buffer overflow designed to overwrite "
+"the return address and skip the instruction immediately following the "
+"function call. (Inspired by crossref:bibliography[Phrack,4])"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:138
+#, no-wrap
+msgid "#include <stdio.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:143
+#, no-wrap
+msgid ""
+"void manipulate(char *buffer) {\n"
+" char newbuffer[80];\n"
+" strcpy(newbuffer,buffer);\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:147
+#, no-wrap
+msgid ""
+"int main() {\n"
+" char ch,buffer[4096];\n"
+" int i=0;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:149
+#, no-wrap
+msgid " while ((buffer[i++] = getchar()) != '\\n') {};\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:156
+#, no-wrap
+msgid ""
+" i=1;\n"
+" manipulate(buffer);\n"
+" i=2;\n"
+" printf(\"The value of i is : %d\\n\",i);\n"
+" return 0;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:159
+msgid ""
+"Let us examine what the memory image of this process would look like if we "
+"were to input 160 spaces into our little program before hitting return."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:163
+msgid ""
+"Obviously more malicious input can be devised to execute actual compiled "
+"instructions (such as exec(/bin/sh))."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:164
+#, no-wrap
+msgid "Avoiding Buffer Overflows"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:174
+msgid ""
+"The most straightforward solution to the problem of stack-overflows is to "
+"always use length restricted memory and string copy functions. `strncpy` "
+"and `strncat` are part of the standard C library. These functions accept a "
+"length value as a parameter which should be no larger than the size of the "
+"destination buffer. These functions will then copy up to 'length' bytes "
+"from the source to the destination. However there are a number of problems "
+"with these functions. Neither function guarantees NUL termination if the "
+"size of the input buffer is as large as the destination. The length "
+"parameter is also used inconsistently between strncpy and strncat so it is "
+"easy for programmers to get confused as to their proper usage. There is "
+"also a significant performance loss compared to `strcpy` when copying a "
+"short string into a large buffer since `strncpy` NUL fills up the size "
+"specified."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:177
+msgid ""
+"Another memory copy implementation exists to get around these problems. The "
+"`strlcpy` and `strlcat` functions guarantee that they will always null "
+"terminate the destination string when given a non-zero length argument."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:178
+#, no-wrap
+msgid "Compiler based run-time bounds checking"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:182
+msgid ""
+"Unfortunately there is still a very large assortment of code in public use "
+"which blindly copies memory around without using any of the bounded copy "
+"routines we just discussed. Fortunately, there is a way to help prevent "
+"such attacks - run-time bounds checking, which is implemented by several C/C+"
+"+ compilers."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:185
+msgid ""
+"ProPolice is one such compiler feature, and is integrated into man:gcc[1] "
+"versions 4.1 and later. It replaces and extends the earlier StackGuard man:"
+"gcc[1] extension."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:189
+msgid ""
+"ProPolice helps to protect against stack-based buffer overflows and other "
+"attacks by laying pseudo-random numbers in key areas of the stack before "
+"calling any function. When a function returns, these \"canaries\" are "
+"checked and if they are found to have been changed the executable is "
+"immediately aborted. Thus any attempt to modify the return address or other "
+"variable stored on the stack in an attempt to get malicious code to run is "
+"unlikely to succeed, as the attacker would have to also manage to leave the "
+"pseudo-random canaries untouched."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:191
+msgid ""
+"Recompiling your application with ProPolice is an effective means of "
+"stopping most buffer-overflow attacks, but it can still be compromised."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:192
+#, no-wrap
+msgid "Library based run-time bounds checking"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:196
+msgid ""
+"Compiler-based mechanisms are completely useless for binary-only software "
+"for which you cannot recompile. For these situations there are a number of "
+"libraries which re-implement the unsafe functions of the C-library "
+"(`strcpy`, `fscanf`, `getwd`, etc..) and ensure that these functions can "
+"never write past the stack pointer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:198
+msgid "libsafe"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:199
+msgid "libverify"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:200
+msgid "libparanoia"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:205
+msgid ""
+"Unfortunately these library-based defenses have a number of shortcomings. "
+"These libraries only protect against a very small set of security related "
+"issues and they neglect to fix the actual problem. These defenses may fail "
+"if the application was compiled with -fomit-frame-pointer. Also, the "
+"LD_PRELOAD and LD_LIBRARY_PATH environment variables can be overwritten/"
+"unset by the user."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:207
+#, no-wrap
+msgid "SetUID issues"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:211
+msgid ""
+"There are at least 6 different IDs associated with any given process, and "
+"you must therefore be very careful with the access that your process has at "
+"any given time. In particular, all seteuid applications should give up "
+"their privileges as soon as it is no longer required."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:214
+msgid ""
+"The real user ID can only be changed by a superuser process. The login "
+"program sets this when a user initially logs in and it is seldom changed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:218
+msgid ""
+"The effective user ID is set by the `exec()` functions if a program has its "
+"seteuid bit set. An application can call `seteuid()` at any time to set the "
+"effective user ID to either the real user ID or the saved set-user-ID. When "
+"the effective user ID is set by `exec()` functions, the previous value is "
+"saved in the saved set-user-ID."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:220
+#, no-wrap
+msgid "Limiting your program's environment"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:228
+msgid ""
+"The traditional method of restricting a process is with the `chroot()` "
+"system call. This system call changes the root directory from which all "
+"other paths are referenced for a process and any child processes. For this "
+"call to succeed the process must have execute (search) permission on the "
+"directory being referenced. The new environment does not actually take "
+"effect until you `chdir()` into your new environment. It should also be "
+"noted that a process can easily break out of a chroot environment if it has "
+"root privilege. This could be accomplished by creating device nodes to read "
+"kernel memory, attaching a debugger to a process outside of the man:"
+"chroot[8] environment, or in many other creative ways."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:233
+msgid ""
+"The behavior of the `chroot()` system call can be controlled somewhat with "
+"the kern.chroot_allow_open_directories `sysctl` variable. When this value "
+"is set to 0, `chroot()` will fail with EPERM if there are any directories "
+"open. If set to the default value of 1, then `chroot()` will fail with "
+"EPERM if there are any directories open and the process is already subject "
+"to a `chroot()` call. For any other value, the check for open directories "
+"will be bypassed completely."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:234
+#, no-wrap
+msgid "FreeBSD's jail functionality"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:238
+msgid ""
+"The concept of a Jail extends upon the `chroot()` by limiting the powers of "
+"the superuser to create a true `virtual server'. Once a prison is set up "
+"all network communication must take place through the specified IP address, "
+"and the power of \"root privilege\" in this jail is severely constrained."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:242
+msgid ""
+"While in a prison, any tests of superuser power within the kernel using the "
+"`suser()` call will fail. However, some calls to `suser()` have been "
+"changed to a new interface `suser_xxx()`. This function is responsible for "
+"recognizing or denying access to superuser power for imprisoned processes."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:244
+msgid "A superuser process within a jailed environment has the power to:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:246
+msgid ""
+"Manipulate credential with `setuid`, `seteuid`, `setgid`, `setegid`, "
+"`setgroups`, `setreuid`, `setregid`, `setlogin`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:247
+msgid "Set resource limits with `setrlimit`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:248
+msgid "Modify some sysctl nodes (kern.hostname)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:249
+msgid "`chroot()`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:250
+msgid "Set flags on a vnode: `chflags`, `fchflags`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:251
+msgid ""
+"Set attributes of a vnode such as file permission, owner, group, size, "
+"access time, and modification time."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:252
+msgid "Bind to privileged ports in the Internet domain (ports < 1024)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:256
+msgid ""
+"`Jail` is a very useful tool for running applications in a secure "
+"environment but it does have some shortcomings. Currently, the IPC "
+"mechanisms have not been converted to the `suser_xxx` so applications such "
+"as MySQL cannot be run within a jail. Superuser access may have a very "
+"limited meaning within a jail, but there is no way to specify exactly what "
+"\"very limited\" means."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:257
+#, no-wrap
+msgid "POSIX(R).1e Process Capabilities"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:260
+msgid ""
+"POSIX(R) has released a working draft that adds event auditing, access "
+"control lists, fine grained privileges, information labeling, and mandatory "
+"access control."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:263
+msgid ""
+"This is a work in progress and is the focus of the http://www.trustedbsd.org/"
+"[TrustedBSD] project. Some of the initial work has been committed to "
+"FreeBSD-CURRENT (cap_set_proc(3))."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:265
+#, no-wrap
+msgid "Trust"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:269
+msgid ""
+"An application should never assume that anything about the users environment "
+"is sane. This includes (but is certainly not limited to): user input, "
+"signals, environment variables, resources, IPC, mmaps, the filesystem "
+"working directory, file descriptors, the # of open files, etc."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:274
+msgid ""
+"You should never assume that you can catch all forms of invalid input that a "
+"user might supply. Instead, your application should use positive filtering "
+"to only allow a specific subset of inputs that you deem safe. Improper data "
+"validation has been the cause of many exploits, especially with CGI scripts "
+"on the world wide web. For filenames you need to be extra careful about "
+"paths (\"../\", \"/\"), symbolic links, and shell escape characters."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:277
+msgid ""
+"Perl has a really cool feature called \"Taint\" mode which can be used to "
+"prevent scripts from using data derived outside the program in an unsafe "
+"way. This mode will check command line arguments, environment variables, "
+"locale information, the results of certain syscalls (`readdir()`, "
+"`readlink()`, `getpwxxx()`), and all file input."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:279
+#, no-wrap
+msgid "Race Conditions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:283
+msgid ""
+"A race condition is anomalous behavior caused by the unexpected dependence "
+"on the relative timing of events. In other words, a programmer incorrectly "
+"assumed that a particular event would always happen before another."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:289
+msgid ""
+"Some of the common causes of race conditions are signals, access checks, and "
+"file opens. Signals are asynchronous events by nature so special care must "
+"be taken in dealing with them. Checking access with `access(2)` then "
+"`open(2)` is clearly non-atomic. Users can move files in between the two "
+"calls. Instead, privileged applications should `seteuid()` and then call "
+"`open()` directly. Along the same lines, an application should always set a "
+"proper umask before `open()` to obviate the need for spurious `chmod()` "
+"calls."
+msgstr ""