SAFE_FOPEN_WRAPPER(3)
π
safe_fopen_wrapper(3): the safe stream-opening bestie π
okay so bestie, this is the manual page for safe_fopen_wrapper(3) β the whole safe_fopen / safe_fcreate family that opens and creates streams without letting symlink gremlins ruin your day. no cap, it's giving secure file-opening main character energy. π¦β¨
π NAME π
Meet the whole crew: safe_fopen_wrapper, safe_fopen_wrapper_follow, safe_fopen_no_fcreate, safe_fopen_no_fcreate_follow, safe_fcreate_fail_if_exists, safe_fcreate_replace_if_exists, safe_fcreate_keep_if_exists, and safe_fcreate_keep_if_exists_follow β they all safely open or create a stream π
β¨ SYNOPSIS β¨
#include "safe_fopen.h"
FILE *safe_fopen_wrapper(const char *fn, const char *mode, mode_t
perms);
FILE *safe_fopen_wrapper_follow(const char *fn, const char *mode, mode_t
perms);
FILE *safe_fopen_no_create(const char *fn, const char *mode);
FILE *safe_fopen_no_create_follow(const char *fn, const char *mode);
FILE *safe_fcreate_fail_if_exists(const char *fn, const char *mode,
mode_t perms);
FILE *safe_fcreate_keep_if_exists(const char *fn, const char *mode,
mode_t perms);
FILE *safe_fcreate_keep_if_exists_follow(const char *fn, const char
*mode, mode_t perms);
FILE *safe_fcreate_replace_if_exists(const char *fn, const char *mode,
mode_t perms);
π DESCRIPTION π
okay so the functions in the safe_fopen and safe_fcreate family are replacement functions for fopen(3). They open or create a file whose path name is fn and hand you back a stream associated with that file. π«Ά They're literally designed to prevent common types of symbolic link attacks where the last component of the file name is a symbolic link when creating a file and optionally when opening an existing file. They also make the initial permissions for a newly created file, perms, a required parameter, so an appropriate value is likely to be used. periodt.
safe_fopen_wrapper and safe_fopen_wrapper_follow are meant to be easy replacement functions for existing uses of fopen(3). The knowledgeable developers can use the remaining functions to tailor the specific behavior desired for each use of fopen(3). iykyk. π
All the functions differ from fopen(3) in their treatment of the last component of the file name being a symbolic link. They all fail if an attempt is made to create the file when the last component is a symbolic link (just like the behavior of open(2) using flags of O_CREAT with O_EXCL). safe_fopen_wrapper, safe_fopen_no_create, and safe_fcreate_keep_if_exists also fail when opening an existing file if the last component is a symbolic link. π«π
The functions also differ from fopen(3) in that any of the functions that could possibly create a file require the perms parameter. Other differences and the behavior of each function are explained below in the Functions section. keep scrolling, bestie. π
ποΈ Parameters ποΈ
fnβ the file name to open or create. ποΈmodeβ this is a mode string as specified infopen(3). It consists of multiple characters specifying the behavior of the function. ποΈpermsβ the initial permissions for a newly created file (the actual permission assigned is further restricted by the process'sumask). This is a set of bitwise-or'd permissions as specified inopen(2). This parameter is required by all functions that create files, and is not implicitly derived from the process'sumaskas withfopen(3). In C++, this value has a default value of read and write for the owner (0600), and may be omitted. π
π
Direct fopen(3) Replacement Functions π
safe_fopen_wrapperβ meant to be a direct replacement forfopen(3). The behavior ofsafe_fopen_wrapperis based on the value ofmodeat run-time. Ifmodeis"r"(open for reading),safe_fopen_no_createis called. Otherwise ifmodeis"w"(open for writing) or"a"(open for appending),safe_fcreate_keep_if_existsis called. This function differs fromfopen(3)if the last component of the file name is a symbolic link β the function fails by returningNULLwitherrnoset toEEXIST. πsafe_fopen_wrapper_followβ this function is the same assafe_fopen_wrapperexcept it attempts to follow a symbolic link if it is the last component of the file name and the file exists. π¦
π₯ Advanced fopen(3) Replacement Functions π₯
safe_fopen_no_createβ opens an existing file, and never creates a file if it does not exist, even with a mode of"a"or"w". It also fails if the last component of the file name is a symbolic link. πΈsafe_fopen_no_create_followβ same assafe_fopen_no_createexcept it attempts to follow a symbolic link if it is the last component of the file name and the file exists. π§safe_fcreate_fail_if_existsβ attempts to create the file. It fails if the file already exists or the last component of the file name is a symbolic link by returningNULLwitherrnoset toEEXISTS. πsafe_fcreate_keep_if_existsβ opens a file if it exists or creates it if it does not exist. This function differs fromfopen(3)in that it fails if the last component is a symbolic link. πsafe_fcreate_keep_if_exists_followβ same assafe_fcreate_keep_if_existsexcept it attempts to follow a symbolic link if it is the last component of the file name and the file exists. πsafe_fcreate_replace_if_existsβ always creates a new file, first removing the directory entry thatfnrefers to. The function fails if it cannot perform this task. π₯
π΅οΈ Path manipulation detection and warning facility π΅οΈ
A path manipulation of fn is detected when the file system object referred to by fn changes to a different file system object during the operation of these functions. π
If a path manipulation is detected, the functions retry their operations a set number of times until a path manipulation is not detected. After a set number of times, they return NULL with errno set to EAGAIN. π
All of the open replacement functions also support registering a call back function with safe_open_register_path_warning_callback(3). Each time a path manipulation is detected, the callback function is called. If the callback returns a non-zero result the function immediately fails by returning NULL to the caller. π
π RETURN VALUE π
When successful, these functions return the stream associated with the file at the path name, fn, and errno is unchanged. If an error occurs, NULL is returned and errno is set to an appropriate value. β¨
π ERRORS π
Depending on the function, errno may be set to any of the possible values that open, fdopen, lstat, ftruncate, fstat, fstat, and unlink may use if they fail. Other than the standard behavior of fopen(3), the following errors may occur that would not occur in fopen(3):
EINVALβfnisNULLormodeis invalid.EEXISTβ The last component offnis a symbolic link when the file needs to be created insafe_fopen_wrapper,safe_fopen_wrapper_follow,safe_fcreate_fail_if_exists,safe_fcreate_keep_if_existsandsafe_fcreate_keep_if_exists_follow. It is also returned in the case of opening an existing file where the last component of the file name,fn, is a symbolic link in the functionssafe_fopen_wrapper,safe_fopen_no_createandsafe_fcreate_keep_if_exists.EPERMβ If the functionsafe_fcreate_replace_if_existscannot removefn.EAGAINβ An active attack is occurring on the filename and the function was unable to safely perform the requested action after repeated attempts. All functions can return this exceptsafe_fcreate_fail_if_exists. The application may retry the function and should eventually succeed.
βοΈ AUTHOR βοΈ
Written by James A. Kupsch π
π SEE ALSO π
"How to Open a File and Not Get Hacked", 2008 Third International Conference on Availability, Reliability and Security (ARES)," Barcelona, Spain, March 2008, http://research.cs.wisc.edu/mist/safefile
xoxo, your safe_fopen_wrapper(3) page π β source/version: SAFE_FOPEN_WRAPPER(3), dated 2011-07-26. stay safe out there, bestie. πβ¨
π¦ where this page comes from
- nixos 26.05: safefile 1.0.5
- nixpkgs unstable: safefile 1.0.5
- Copyright 2007-2008, 2011 James A. Kupsch
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms