diff options
author | Nick Kralevich <nnk@google.com> | 2012-06-26 15:08:06 -0700 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2012-06-26 15:19:12 -0700 |
commit | 8118f62a7d3f1af1edb47e0bc2a49af1d523ae0f (patch) | |
tree | c385eb2c8e0d083fbc9b8715d2f15b3ac0fc6908 | |
parent | b52e4385c403d18a68309e568ac729c787d900c4 (diff) | |
download | bionic-8118f62a7d3f1af1edb47e0bc2a49af1d523ae0f.zip bionic-8118f62a7d3f1af1edb47e0bc2a49af1d523ae0f.tar.gz bionic-8118f62a7d3f1af1edb47e0bc2a49af1d523ae0f.tar.bz2 |
FORTIFY_SOURCE: add open() checks
Add a FORTIFY_SOURCE check which requires that you pass a
"mode" argument when calling open(..., O_CREAT). If a mode isn't
passed, then the file is created with "undefined" permissions.
Change-Id: I4427be4f9ce170c69da01af5b00fb05b03613a28
-rw-r--r-- | libc/include/fcntl.h | 40 | ||||
-rw-r--r-- | libc/unistd/open.c | 14 |
2 files changed, 54 insertions, 0 deletions
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h index 7219dd7..47151f4 100644 --- a/libc/include/fcntl.h +++ b/libc/include/fcntl.h @@ -49,6 +49,46 @@ extern int unlinkat(int dirfd, const char *pathname, int flags); extern int fcntl(int fd, int command, ...); extern int creat(const char* path, mode_t mode); +#if defined(__BIONIC_FORTIFY_INLINE) + +# if !defined(__clang__) +/* + * Clang doesn't have support for __builtin_va_arg_pack() + * and __builtin_va_arg_pack_len() + * + * http://clang.llvm.org/docs/UsersManual.html#c_unimpl_gcc + */ + +extern void __open_creat_error() + __attribute__((__error__ ("open called with O_CREAT, but missing mode"))); +extern void __open_toomanyargs_error() + __attribute__((__error__ ("open called with too many arguments"))); +extern int __open_real(const char *pathname, int flags, ...) + __asm__(__USER_LABEL_PREFIX__ "open"); +extern int __open_2(const char *, int); + +__BIONIC_FORTIFY_INLINE +int open(const char *pathname, int flags, ...) { + if (__builtin_constant_p(flags)) { + if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) { + __open_creat_error(); // compile time error + } + } + + if (__builtin_va_arg_pack_len() > 1) { + __open_toomanyargs_error(); // compile time error + } + + if (__builtin_va_arg_pack_len() == 0) { + return __open_2(pathname, flags); + } + + return __open_real(pathname, flags, __builtin_va_arg_pack()); +} + +#endif /* !defined(__clang__) */ +#endif /* defined(__BIONIC_FORTIFY_INLINE) */ + __END_DECLS #endif /* _FCNTL_H */ diff --git a/libc/unistd/open.c b/libc/unistd/open.c index 03cba45..56602db 100644 --- a/libc/unistd/open.c +++ b/libc/unistd/open.c @@ -28,6 +28,8 @@ #include <unistd.h> #include <fcntl.h> #include <stdarg.h> +#include <stdlib.h> +#include <private/logd.h> extern int __open(const char*, int, int); @@ -49,3 +51,15 @@ int open(const char *pathname, int flags, ...) return __open(pathname, flags, mode); } +int __open_2(const char *pathname, int flags) { + if (flags & O_CREAT) { + __libc_android_log_print(ANDROID_LOG_FATAL, "libc", + "*** open(O_CREAT) called without specifying a mode ***\n"); + abort(); + } + + flags |= O_LARGEFILE; + + return __open(pathname, flags, 0); +} + |