Skip to content

Commit ae3527e

Browse files
committedAug 16, 2017
[clang-tidy] Add a close-on-exec check on accept() in Android module.
Summary: accept() is better to be replaced by accept4() with SOCK_CLOEXEC flag to avoid file descriptor leakage. Differential Revision: https://reviews.llvm.org/D35362 llvm-svn: 311024
1 parent 71ecaa1 commit ae3527e

File tree

8 files changed

+137
-0
lines changed

8 files changed

+137
-0
lines changed
 

‎clang-tools-extra/clang-tidy/android/AndroidTidyModule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../ClangTidy.h"
1111
#include "../ClangTidyModule.h"
1212
#include "../ClangTidyModuleRegistry.h"
13+
#include "CloexecAcceptCheck.h"
1314
#include "CloexecCreatCheck.h"
1415
#include "CloexecDupCheck.h"
1516
#include "CloexecFopenCheck.h"
@@ -29,6 +30,7 @@ namespace android {
2930
class AndroidModule : public ClangTidyModule {
3031
public:
3132
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
33+
CheckFactories.registerCheck<CloexecAcceptCheck>("android-cloexec-accept");
3234
CheckFactories.registerCheck<CloexecCreatCheck>("android-cloexec-creat");
3335
CheckFactories.registerCheck<CloexecDupCheck>("android-cloexec-dup");
3436
CheckFactories.registerCheck<CloexecFopenCheck>("android-cloexec-fopen");

‎clang-tools-extra/clang-tidy/android/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
22

33
add_clang_library(clangTidyAndroidModule
44
AndroidTidyModule.cpp
5+
CloexecAcceptCheck.cpp
56
CloexecCheck.cpp
67
CloexecCreatCheck.cpp
78
CloexecDupCheck.cpp
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===--- CloexecAcceptCheck.cpp - clang-tidy-------------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "CloexecAcceptCheck.h"
11+
#include "clang/AST/ASTContext.h"
12+
#include "clang/ASTMatchers/ASTMatchFinder.h"
13+
14+
using namespace clang::ast_matchers;
15+
16+
namespace clang {
17+
namespace tidy {
18+
namespace android {
19+
20+
void CloexecAcceptCheck::registerMatchers(MatchFinder *Finder) {
21+
auto SockAddrPointerType =
22+
hasType(pointsTo(recordDecl(isStruct(), hasName("sockaddr"))));
23+
auto SockLenPointerType = hasType(pointsTo(namedDecl(hasName("socklen_t"))));
24+
25+
registerMatchersImpl(Finder,
26+
functionDecl(returns(isInteger()), hasName("accept"),
27+
hasParameter(0, hasType(isInteger())),
28+
hasParameter(1, SockAddrPointerType),
29+
hasParameter(2, SockLenPointerType)));
30+
}
31+
32+
void CloexecAcceptCheck::check(const MatchFinder::MatchResult &Result) {
33+
const std::string &ReplacementText =
34+
(Twine("accept4(") + getSpellingArg(Result, 0) + ", " +
35+
getSpellingArg(Result, 1) + ", " + getSpellingArg(Result, 2) +
36+
", SOCK_CLOEXEC)")
37+
.str();
38+
39+
replaceFunc(
40+
Result,
41+
"prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC",
42+
ReplacementText);
43+
}
44+
45+
} // namespace android
46+
} // namespace tidy
47+
} // namespace clang
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===--- CloexecAcceptCheck.h - clang-tidy-----------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
11+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H
12+
13+
#include "CloexecCheck.h"
14+
15+
namespace clang {
16+
namespace tidy {
17+
namespace android {
18+
19+
/// accept() is better to be replaced by accept4().
20+
///
21+
/// For the user-facing documentation see:
22+
/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-accept.html
23+
class CloexecAcceptCheck : public CloexecCheck {
24+
public:
25+
CloexecAcceptCheck(StringRef Name, ClangTidyContext *Context)
26+
: CloexecCheck(Name, Context) {}
27+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
28+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
29+
};
30+
31+
} // namespace android
32+
} // namespace tidy
33+
} // namespace clang
34+
35+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_ACCEPT_H

‎clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ Improvements to clang-tidy
7070
``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,
7171
``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.
7272

73+
- New `android-cloexec-accept
74+
<http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-accept.html>`_ check
75+
76+
Detects usage of ``accept()``.
77+
7378
- New `android-cloexec-dup
7479
<http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-dup.html>`_ check
7580

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.. title:: clang-tidy - android-cloexec-accept
2+
3+
android-cloexec-accept
4+
======================
5+
6+
The usage of ``accept()`` is not recommended, it's better to use ``accept4()``.
7+
Without this flag, an opened sensitive file descriptor would remain open across
8+
a fork+exec to a lower-privileged SELinux domain.
9+
10+
Examples:
11+
12+
.. code-block:: c++
13+
14+
accept(sockfd, addr, addrlen);
15+
16+
// becomes
17+
18+
accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);

‎clang-tools-extra/docs/clang-tidy/checks/list.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Clang-Tidy Checks
44
=================
55

66
.. toctree::
7+
android-cloexec-accept
78
android-cloexec-creat
89
android-cloexec-dup
910
android-cloexec-fopen
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %check_clang_tidy %s android-cloexec-accept %t
2+
3+
struct sockaddr {};
4+
typedef int socklen_t;
5+
#define NULL 0
6+
7+
extern "C" int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
8+
9+
void f() {
10+
accept(0, NULL, NULL);
11+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC [android-cloexec-accept]
12+
// CHECK-FIXES: accept4(0, NULL, NULL, SOCK_CLOEXEC);
13+
}
14+
15+
namespace i {
16+
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
17+
void g() {
18+
accept(0, NULL, NULL);
19+
}
20+
} // namespace i
21+
22+
class C {
23+
public:
24+
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
25+
void h() {
26+
accept(0, NULL, NULL);
27+
}
28+
};

0 commit comments

Comments
 (0)
Please sign in to comment.