unix - How can openat avoid TOCTTOU errors? -
according advanced programming in unix environment, openat()
provides way avoid time-of-check-to-time-of-use (tocttou) errors.
i’m confused how. far know, openat
relies on file descriptor, file descriptor needs opened first - introduce tocttou?
the posix specification openat()
says:
int openat(int
fd
, const char *
path
, int
oflag
, ...);
[…lengthy spiel on regular
open()
…]the
openat()
function shall equivalentopen()
function except in casepath
specifies relative path. in case file opened determined relative directory associated file descriptorfd
instead of current working directory. if file descriptor opened withouto_search
, function shall check whether directory searches permitted using current permissions of directory underlying file descriptor. if file descriptor openedo_search
, function shall not perform check.the
oflag
parameter , optional fourth parameter correspond parameters ofopen()
.if
openat()
passed special valueat_fdcwd
infd
parameter, current working directory shall used , behavior shall identical callopen()
.
this means if want place files in, or relative to, specific directory, can open file descriptor directory (probably o_search
option), , specify path names relative directory in openat()
system call.
other *at()
functions such fstatat()
work similarly.
- how improve security?
first, note file descriptor file descriptor of directory. @ time when directory opened (for reading), existed, , process had permission access directory , files in it. further, because process has directory open, last references directory won't vanish until process closes directory file descriptor. if it's on mounted file system, file system can't unmounted until program terminates (because process has directory open). if directory moved (on same file system), files continue created relative directory in current position in file system.
things more speculative here on — i've not formally tested these observations.
even if directory removed, appears you'd still able create files relative it. if names simple names ("new_file"
or "./new_file"
), should ok. if names have more of path ("subdir/new_file"
), creating or opening file fail if directory has been removed because sub-directories have been removed.
of course, there's mkdirat()
create sub-directories.
presumably, file system has clean after this, quite complex. means there's chance in fact can't create files in directory have open file descriptor name has been removed. however, know no longer possible, rather assuming same directory.
either way, harder attacker confuse program creating files in wrong directory, long you've been careful , consistent in using correct *at()
functions.
one set of toctou attacks removed; attacks depend on directory being renamed (or possibly removed) , instead using new name (e.g. symlink other location) foiled because files continue created relative original directory, not using renamed or replacement directory.
the rationale section of posix specification openat()
says:
the purpose of
openat()
function enable opening files in directories other current working directory without exposure race conditions. part of path of file changed in parallel callopen()
, resulting in unspecified behavior. opening file descriptor target directory , usingopenat()
function can guaranteed opened file located relative desired directory. implementations useopenat()
function other purposes well. in cases, if oflag parameter haso_xattr
bit set, returned file descriptor provides access extended attributes. functionality not standardized here.
Comments
Post a Comment