# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-05-01 19:56-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \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:16 #, no-wrap msgid "Secure Programming" msgstr "" #. type: Title == #: documentation/content/en/books/developers-handbook/secure/_index.adoc:54 #, no-wrap msgid "Synopsis" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:57 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:59 #, no-wrap msgid "Secure Design Methodology" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:64 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:68 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:70 #, no-wrap msgid "Buffer Overflows" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:76 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:85 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:88 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:91 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:97 #, no-wrap msgid "`strcpy`(char *dest, const char *src)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:101 #: documentation/content/en/books/developers-handbook/secure/_index.adoc:106 #, no-wrap msgid "May overflow the dest buffer" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:102 #, no-wrap msgid "`strcat`(char *dest, const char *src)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:107 #, no-wrap msgid "`getwd`(char *buf)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:111 #, no-wrap msgid "May overflow the buf buffer" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:112 #, no-wrap msgid "`gets`(char *s)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:116 #, no-wrap msgid "May overflow the s buffer" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:117 #, no-wrap msgid "`[vf]scanf`(const char *format, ...)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:121 #, no-wrap msgid "May overflow its arguments." msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:122 #, no-wrap msgid "`realpath`(char *path, char resolved_path[])" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:126 #, no-wrap msgid "May overflow the path buffer" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:127 #, no-wrap msgid "`[v]sprintf`(char *str, const char *format, ...)" msgstr "" #. type: Table #: documentation/content/en/books/developers-handbook/secure/_index.adoc:130 #, no-wrap msgid "May overflow the str buffer." msgstr "" #. type: Title === #: documentation/content/en/books/developers-handbook/secure/_index.adoc:132 #, no-wrap msgid "Example Buffer Overflow" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:135 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:139 #, no-wrap msgid "#include \n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/secure/_index.adoc:144 #, 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:148 #, 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:150 #, no-wrap msgid " while ((buffer[i++] = getchar()) != '\\n') {};\n" msgstr "" #. type: delimited block . 4 #: documentation/content/en/books/developers-handbook/secure/_index.adoc:157 #, 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:160 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:164 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:165 #, no-wrap msgid "Avoiding Buffer Overflows" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:175 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:178 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:179 #, no-wrap msgid "Compiler based run-time bounds checking" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:183 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:186 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:190 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:192 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:193 #, no-wrap msgid "Library based run-time bounds checking" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:197 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:199 msgid "libsafe" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:200 msgid "libverify" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:201 msgid "libparanoia" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:206 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:208 #, no-wrap msgid "SetUID issues" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:212 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:215 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:219 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:221 #, no-wrap msgid "Limiting your program's environment" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:229 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:234 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:235 #, no-wrap msgid "FreeBSD's jail functionality" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:239 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:243 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:245 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:247 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:248 msgid "Set resource limits with `setrlimit`" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:249 msgid "Modify some sysctl nodes (kern.hostname)" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:250 msgid "`chroot()`" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:251 msgid "Set flags on a vnode: `chflags`, `fchflags`" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:252 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:253 msgid "Bind to privileged ports in the Internet domain (ports < 1024)" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:257 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:258 #, no-wrap msgid "POSIX(R).1e Process Capabilities" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:261 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:264 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:266 #, no-wrap msgid "Trust" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:270 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:275 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:278 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:280 #, no-wrap msgid "Race Conditions" msgstr "" #. type: Plain text #: documentation/content/en/books/developers-handbook/secure/_index.adoc:284 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:290 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 ""