Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/tests/gtest/TestFilePreferencesUnix.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "gtest/gtest.h"
2
3
#include "mozilla/FilePreferences.h"
4
5
#include "nsDirectoryServiceDefs.h"
6
#include "nsDirectoryServiceUtils.h"
7
#include "mozilla/Preferences.h"
8
#include "mozilla/ScopeExit.h"
9
#include "nsIDirectoryEnumerator.h"
10
11
using namespace mozilla;
12
13
TEST(TestFilePreferencesUnix, Parsing)
14
0
{
15
0
  #define kBlacklisted "/tmp/blacklisted"
16
0
  #define kBlacklistedDir "/tmp/blacklisted/"
17
0
  #define kBlacklistedFile "/tmp/blacklisted/file"
18
0
  #define kOther "/tmp/other"
19
0
  #define kOtherDir "/tmp/other/"
20
0
  #define kOtherFile "/tmp/other/file"
21
0
  #define kAllowed "/tmp/allowed"
22
0
23
0
  // This is run on exit of this function to make sure we clear the pref
24
0
  // and that behaviour with the pref cleared is correct.
25
0
  auto cleanup = MakeScopeExit([&] {
26
0
    nsresult rv = Preferences::ClearUser("network.file.path_blacklist");
27
0
    ASSERT_EQ(rv, NS_OK);
28
0
    FilePreferences::InitPrefs();
29
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklisted)), true);
30
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)), true);
31
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedFile)), true);
32
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kAllowed)), true);
33
0
  });
34
0
35
0
  auto CheckPrefs = [](const nsACString& aPaths)
36
0
  {
37
0
    nsresult rv;
38
0
    rv = Preferences::SetCString("network.file.path_blacklist", aPaths);
39
0
    ASSERT_EQ(rv, NS_OK);
40
0
    FilePreferences::InitPrefs();
41
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)), false);
42
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)), false);
43
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedFile)), false);
44
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklisted)), false);
45
0
    ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kAllowed)), true);
46
0
  };
47
0
48
0
  CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted));
49
0
  CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted "," kOther));
50
0
  ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kOtherFile)), false);
51
0
  CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted "," kOther ","));
52
0
  ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kOtherFile)), false);
53
0
}
54
55
TEST(TestFilePreferencesUnix, Simple)
56
0
{
57
0
  nsAutoCString tempPath;
58
0
59
0
  // This is the directory we will blacklist
60
0
  nsCOMPtr<nsIFile> blacklistedDir;
61
0
  nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(blacklistedDir));
62
0
  ASSERT_EQ(rv, NS_OK);
63
0
  rv = blacklistedDir->GetNativePath(tempPath);
64
0
  ASSERT_EQ(rv, NS_OK);
65
0
  rv = blacklistedDir->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
66
0
  ASSERT_EQ(rv, NS_OK);
67
0
68
0
  // This is executed at exit to clean up after ourselves.
69
0
  auto cleanup = MakeScopeExit([&] {
70
0
    nsresult rv = Preferences::ClearUser("network.file.path_blacklist");
71
0
    ASSERT_EQ(rv, NS_OK);
72
0
    FilePreferences::InitPrefs();
73
0
74
0
    rv = blacklistedDir->Remove(true);
75
0
    ASSERT_EQ(rv, NS_OK);
76
0
  });
77
0
78
0
  // Create the directory
79
0
  rv = blacklistedDir->Create(nsIFile::DIRECTORY_TYPE, 0666);
80
0
  ASSERT_EQ(rv, NS_OK);
81
0
82
0
  // This is the file we will try to access
83
0
  nsCOMPtr<nsIFile> blacklistedFile;
84
0
  rv = blacklistedDir->Clone(getter_AddRefs(blacklistedFile));
85
0
  ASSERT_EQ(rv, NS_OK);
86
0
  rv = blacklistedFile->AppendNative(NS_LITERAL_CSTRING("test_file"));
87
0
88
0
  // Create the file
89
0
  ASSERT_EQ(rv, NS_OK);
90
0
  rv = blacklistedFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
91
0
92
0
  // Get the path for the blacklist
93
0
  nsAutoCString blackListPath;
94
0
  rv = blacklistedDir->GetNativePath(blackListPath);
95
0
  ASSERT_EQ(rv, NS_OK);
96
0
97
0
  // Set the pref and make sure it is enforced
98
0
  rv = Preferences::SetCString("network.file.path_blacklist", blackListPath);
99
0
  ASSERT_EQ(rv, NS_OK);
100
0
  FilePreferences::InitPrefs();
101
0
102
0
  // Check that we can't access some of the file attributes
103
0
  int64_t size;
104
0
  rv = blacklistedFile->GetFileSize(&size);
105
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
106
0
107
0
  bool exists;
108
0
  rv = blacklistedFile->Exists(&exists);
109
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
110
0
111
0
  // Check that we can't enumerate the directory
112
0
  nsCOMPtr<nsIDirectoryEnumerator> dirEnumerator;
113
0
  rv = blacklistedDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
114
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
115
0
116
0
  nsCOMPtr<nsIFile> newPath;
117
0
  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
118
0
  ASSERT_EQ(rv, NS_OK);
119
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING("."));
120
0
  ASSERT_EQ(rv, NS_OK);
121
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
122
0
  ASSERT_EQ(rv, NS_OK);
123
0
  rv = newPath->Exists(&exists);
124
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
125
0
126
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING("test_file"));
127
0
  ASSERT_EQ(rv, NS_OK);
128
0
  rv = newPath->Exists(&exists);
129
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
130
0
131
0
  // Check that ./ does not bypass the filter
132
0
  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
133
0
  ASSERT_EQ(rv, NS_OK);
134
0
  rv = newPath->AppendRelativeNativePath(NS_LITERAL_CSTRING("./blacklisted_dir/file"));
135
0
  ASSERT_EQ(rv, NS_OK);
136
0
  rv = newPath->Exists(&exists);
137
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
138
0
139
0
  // Check that ..  does not bypass the filter
140
0
  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
141
0
  ASSERT_EQ(rv, NS_OK);
142
0
  rv = newPath->AppendRelativeNativePath(NS_LITERAL_CSTRING("allowed/../blacklisted_dir/file"));
143
0
  ASSERT_EQ(rv, NS_OK);
144
0
  rv = newPath->Exists(&exists);
145
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
146
0
147
0
  rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
148
0
  ASSERT_EQ(rv, NS_OK);
149
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING("allowed"));
150
0
  ASSERT_EQ(rv, NS_OK);
151
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING(".."));
152
0
  ASSERT_EQ(rv, NS_OK);
153
0
  rv = newPath->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
154
0
  ASSERT_EQ(rv, NS_OK);
155
0
  rv = newPath->Exists(&exists);
156
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
157
0
158
0
  nsAutoCString trickyPath(tempPath);
159
0
  trickyPath.AppendLiteral("/allowed/../blacklisted_dir/file");
160
0
  rv = newPath->InitWithNativePath(trickyPath);
161
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
162
0
163
0
  // Check that we can't construct a path that is functionally the same
164
0
  // as the blacklisted one and bypasses the filter.
165
0
  trickyPath = tempPath;
166
0
  trickyPath.AppendLiteral("/./blacklisted_dir/file");
167
0
  rv = newPath->InitWithNativePath(trickyPath);
168
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
169
0
170
0
  trickyPath = tempPath;
171
0
  trickyPath.AppendLiteral("//blacklisted_dir/file");
172
0
  rv = newPath->InitWithNativePath(trickyPath);
173
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
174
0
175
0
  trickyPath.Truncate();
176
0
  trickyPath.AppendLiteral("//");
177
0
  trickyPath.Append(tempPath);
178
0
  trickyPath.AppendLiteral("/blacklisted_dir/file");
179
0
  rv = newPath->InitWithNativePath(trickyPath);
180
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
181
0
182
0
  trickyPath.Truncate();
183
0
  trickyPath.AppendLiteral("//");
184
0
  trickyPath.Append(tempPath);
185
0
  trickyPath.AppendLiteral("//blacklisted_dir/file");
186
0
  rv = newPath->InitWithNativePath(trickyPath);
187
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
188
0
189
0
  // Check that if the blacklisted string is a directory, we only block access
190
0
  // to subresources, not the directory itself.
191
0
  nsAutoCString blacklistDirPath(blackListPath);
192
0
  blacklistDirPath.Append("/");
193
0
  rv = Preferences::SetCString("network.file.path_blacklist", blacklistDirPath);
194
0
  ASSERT_EQ(rv, NS_OK);
195
0
  FilePreferences::InitPrefs();
196
0
197
0
  // This should work, since we only block subresources
198
0
  rv = blacklistedDir->Exists(&exists);
199
0
  ASSERT_EQ(rv, NS_OK);
200
0
201
0
  rv = blacklistedDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
202
0
  ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
203
0
}