forked from OSchip/llvm-project
[clang-tidy] Add a close-on-exec check on epoll_create1() in Android module.
Summary: epoll_create1() is better to set EPOLL_CLOEXEC flag to avoid file descriptor leakage. Differential Revision: https://reviews.llvm.org/D35365 llvm-svn: 311028
This commit is contained in:
parent
5ac20c9c25
commit
3be4ecb15b
|
@ -13,6 +13,7 @@
|
|||
#include "CloexecAccept4Check.h"
|
||||
#include "CloexecAcceptCheck.h"
|
||||
#include "CloexecCreatCheck.h"
|
||||
#include "CloexecEpollCreate1Check.h"
|
||||
#include "CloexecDupCheck.h"
|
||||
#include "CloexecFopenCheck.h"
|
||||
#include "CloexecInotifyInit1Check.h"
|
||||
|
@ -34,6 +35,8 @@ public:
|
|||
CheckFactories.registerCheck<CloexecAccept4Check>("android-cloexec-accept4");
|
||||
CheckFactories.registerCheck<CloexecAcceptCheck>("android-cloexec-accept");
|
||||
CheckFactories.registerCheck<CloexecCreatCheck>("android-cloexec-creat");
|
||||
CheckFactories.registerCheck<CloexecEpollCreate1Check>(
|
||||
"android-cloexec-epoll-create1");
|
||||
CheckFactories.registerCheck<CloexecDupCheck>("android-cloexec-dup");
|
||||
CheckFactories.registerCheck<CloexecFopenCheck>("android-cloexec-fopen");
|
||||
CheckFactories.registerCheck<CloexecInotifyInitCheck>(
|
||||
|
|
|
@ -6,6 +6,7 @@ add_clang_library(clangTidyAndroidModule
|
|||
CloexecAcceptCheck.cpp
|
||||
CloexecCheck.cpp
|
||||
CloexecCreatCheck.cpp
|
||||
CloexecEpollCreate1Check.cpp
|
||||
CloexecDupCheck.cpp
|
||||
CloexecFopenCheck.cpp
|
||||
CloexecInotifyInit1Check.cpp
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
//===--- CloexecEpollCreate1Check.cpp - clang-tidy-------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CloexecEpollCreate1Check.h"
|
||||
#include "../utils/ASTUtils.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace android {
|
||||
|
||||
void CloexecEpollCreate1Check::registerMatchers(MatchFinder *Finder) {
|
||||
registerMatchersImpl(
|
||||
Finder, functionDecl(returns(isInteger()), hasName("epoll_create1"),
|
||||
hasParameter(0, hasType(isInteger()))));
|
||||
}
|
||||
|
||||
void CloexecEpollCreate1Check::check(const MatchFinder::MatchResult &Result) {
|
||||
insertMacroFlag(Result, /*MarcoFlag=*/"EPOLL_CLOEXEC", /*ArgPos=*/0);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
|
@ -0,0 +1,35 @@
|
|||
//===--- CloexecEpollCreate1Check.h - clang-tidy-----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
|
||||
|
||||
#include "CloexecCheck.h"
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace android {
|
||||
|
||||
/// Finds code that uses epoll_create1() without using the EPOLL_CLOEXEC flag.
|
||||
///
|
||||
/// For the user-facing documentation see:
|
||||
/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create1.html
|
||||
class CloexecEpollCreate1Check : public CloexecCheck {
|
||||
public:
|
||||
CloexecEpollCreate1Check(StringRef Name, ClangTidyContext *Context)
|
||||
: CloexecCheck(Name, Context) {}
|
||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_EPOLL_CREATE1_H
|
|
@ -91,6 +91,12 @@ Improvements to clang-tidy
|
|||
|
||||
Detects usage of ``inotify_init()``.
|
||||
|
||||
- New `android-cloexec-epoll-create1
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-epoll-create1.html>`_ check
|
||||
|
||||
Checks if the required file flag ``EPOLL_CLOEXEC`` is present in the argument of
|
||||
``epoll_create1()``.
|
||||
|
||||
- New `android-cloexec-memfd_create
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-memfd_create.html>`_ check
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
.. title:: clang-tidy - android-cloexec-epoll-create1
|
||||
|
||||
android-cloexec-epoll-create1
|
||||
=============================
|
||||
|
||||
``epoll_create1()`` should include ``EPOLL_CLOEXEC`` in its type argument to
|
||||
avoid the file descriptor leakage. Without this flag, an opened sensitive file
|
||||
would remain open across a fork+exec to a lower-privileged SELinux domain.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
epoll_create1(0);
|
||||
|
||||
// becomes
|
||||
|
||||
epoll_create1(EPOLL_CLOEXEC);
|
|
@ -7,6 +7,7 @@ Clang-Tidy Checks
|
|||
android-cloexec-accept
|
||||
android-cloexec-accept4
|
||||
android-cloexec-creat
|
||||
android-cloexec-epoll-create1
|
||||
android-cloexec-dup
|
||||
android-cloexec-fopen
|
||||
android-cloexec-inotify-init
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// RUN: %check_clang_tidy %s android-cloexec-epoll-create1 %t
|
||||
|
||||
#define __O_CLOEXEC 3
|
||||
#define EPOLL_CLOEXEC __O_CLOEXEC
|
||||
#define TEMP_FAILURE_RETRY(exp) \
|
||||
({ \
|
||||
int _rc; \
|
||||
do { \
|
||||
_rc = (exp); \
|
||||
} while (_rc == -1); \
|
||||
})
|
||||
|
||||
extern "C" int epoll_create1(int flags);
|
||||
|
||||
void a() {
|
||||
epoll_create1(0);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1' should use EPOLL_CLOEXEC where possible [android-cloexec-epoll-create1]
|
||||
// CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(0));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
|
||||
// CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
|
||||
}
|
||||
|
||||
void f() {
|
||||
epoll_create1(3);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'epoll_create1'
|
||||
// CHECK-FIXES: epoll_create1(EPOLL_CLOEXEC);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(3));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'epoll_create1'
|
||||
// CHECK-FIXES: TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
|
||||
|
||||
int flag = 0;
|
||||
epoll_create1(EPOLL_CLOEXEC);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
|
||||
}
|
||||
|
||||
namespace i {
|
||||
int epoll_create1(int flags);
|
||||
|
||||
void d() {
|
||||
epoll_create1(0);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(0));
|
||||
}
|
||||
|
||||
} // namespace i
|
||||
|
||||
void e() {
|
||||
epoll_create1(EPOLL_CLOEXEC);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
|
||||
}
|
||||
|
||||
class G {
|
||||
public:
|
||||
int epoll_create1(int flags);
|
||||
void d() {
|
||||
epoll_create1(EPOLL_CLOEXEC);
|
||||
TEMP_FAILURE_RETRY(epoll_create1(EPOLL_CLOEXEC));
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue