summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2012-06-27 12:56:52 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-06-27 12:56:52 -0700
commitbd73eede4661298ddbdafa510c3af347683b5f60 (patch)
tree1f456b74c7ad4f9ca906c0f0d2b67c411a77ecf8
parentcb228fb4a91bdccfd974b8a4f45e2b6002e90728 (diff)
parent8118f62a7d3f1af1edb47e0bc2a49af1d523ae0f (diff)
downloadbionic-bd73eede4661298ddbdafa510c3af347683b5f60.zip
bionic-bd73eede4661298ddbdafa510c3af347683b5f60.tar.gz
bionic-bd73eede4661298ddbdafa510c3af347683b5f60.tar.bz2
Merge "FORTIFY_SOURCE: add open() checks"
-rw-r--r--libc/include/fcntl.h40
-rw-r--r--libc/unistd/open.c14
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);
+}
+