policy_low_level_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sandbox/win/src/policy_low_level.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include "sandbox/win/src/policy_engine_params.h"
  8. #include "sandbox/win/src/policy_engine_processor.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #define POLPARAMS_BEGIN(x) sandbox::ParameterSet x[] = {
  11. #define POLPARAM(p) sandbox::ParamPickerMake(p),
  12. #define POLPARAMS_END }
  13. namespace sandbox {
  14. // Testing that we allow opcode generation on valid string patterns.
  15. TEST(PolicyEngineTest, StringPatternsOK) {
  16. PolicyRule pr(ASK_BROKER);
  17. EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\adobe\\ver??\\", CASE_SENSITIVE));
  18. EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"*.tmp", CASE_SENSITIVE));
  19. EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\*.doc", CASE_SENSITIVE));
  20. EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\windows\\*", CASE_SENSITIVE));
  21. EXPECT_TRUE(
  22. pr.AddStringMatch(IF, 0, L"d:\\adobe\\acrobat.exe", CASE_SENSITIVE));
  23. }
  24. // Testing that we signal invalid string patterns.
  25. TEST(PolicyEngineTest, StringPatternsBAD) {
  26. PolicyRule pr(ASK_BROKER);
  27. EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"one**two", CASE_SENSITIVE));
  28. EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"**three", CASE_SENSITIVE));
  29. EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"five?six*?seven", CASE_SENSITIVE));
  30. EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"eight?*nine", CASE_SENSITIVE));
  31. }
  32. // Helper function to allocate space (on the heap) for policy.
  33. PolicyGlobal* MakePolicyMemory() {
  34. const size_t kTotalPolicySz = 4096 * 8;
  35. char* mem = new char[kTotalPolicySz];
  36. memset(mem, 0, kTotalPolicySz);
  37. PolicyGlobal* policy = reinterpret_cast<PolicyGlobal*>(mem);
  38. policy->data_size = kTotalPolicySz - sizeof(PolicyGlobal);
  39. return policy;
  40. }
  41. // The simplest test using LowLevelPolicy it should test a single opcode which
  42. // does a exact string comparison.
  43. TEST(PolicyEngineTest, SimpleStrMatch) {
  44. PolicyRule pr(ASK_BROKER);
  45. EXPECT_TRUE(
  46. pr.AddStringMatch(IF, 0, L"z:\\Directory\\domo.txt", CASE_INSENSITIVE));
  47. PolicyGlobal* policy = MakePolicyMemory();
  48. const IpcTag kFakeService = IpcTag::PING2;
  49. LowLevelPolicy policyGen(policy);
  50. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  51. EXPECT_TRUE(policyGen.Done());
  52. const wchar_t* filename = L"Z:\\Directory\\domo.txt";
  53. POLPARAMS_BEGIN(eval_params)
  54. POLPARAM(filename) // Argument 0
  55. POLPARAMS_END;
  56. PolicyResult result;
  57. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  58. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  59. EXPECT_EQ(POLICY_MATCH, result);
  60. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  61. filename = L"Z:\\Directory\\domo.txt.tmp";
  62. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  63. EXPECT_EQ(NO_POLICY_MATCH, result);
  64. delete[] reinterpret_cast<char*>(policy);
  65. }
  66. TEST(PolicyEngineTest, SimpleIfNotStrMatch) {
  67. PolicyRule pr(ASK_BROKER);
  68. EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\", CASE_SENSITIVE));
  69. PolicyGlobal* policy = MakePolicyMemory();
  70. const IpcTag kFakeService = IpcTag::PING2;
  71. LowLevelPolicy policyGen(policy);
  72. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  73. EXPECT_TRUE(policyGen.Done());
  74. const wchar_t* filename = nullptr;
  75. POLPARAMS_BEGIN(eval_params)
  76. POLPARAM(filename) // Argument 0
  77. POLPARAMS_END;
  78. PolicyResult result;
  79. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  80. filename = L"c:\\Microsoft\\";
  81. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  82. EXPECT_EQ(NO_POLICY_MATCH, result);
  83. filename = L"c:\\MicroNerd\\";
  84. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  85. EXPECT_EQ(POLICY_MATCH, result);
  86. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  87. filename = L"c:\\Microsoft\\domo.txt";
  88. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  89. EXPECT_EQ(POLICY_MATCH, result);
  90. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  91. delete[] reinterpret_cast<char*>(policy);
  92. }
  93. TEST(PolicyEngineTest, SimpleIfNotStrMatchWild1) {
  94. PolicyRule pr(ASK_BROKER);
  95. EXPECT_TRUE(
  96. pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*", CASE_SENSITIVE));
  97. PolicyGlobal* policy = MakePolicyMemory();
  98. const IpcTag kFakeService = IpcTag::NTCREATEFILE;
  99. LowLevelPolicy policyGen(policy);
  100. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  101. EXPECT_TRUE(policyGen.Done());
  102. const wchar_t* filename = nullptr;
  103. POLPARAMS_BEGIN(eval_params)
  104. POLPARAM(filename) // Argument 0
  105. POLPARAMS_END;
  106. PolicyResult result;
  107. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  108. filename = L"c:\\Microsoft\\domo.txt";
  109. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  110. EXPECT_EQ(NO_POLICY_MATCH, result);
  111. filename = L"c:\\MicroNerd\\domo.txt";
  112. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  113. EXPECT_EQ(POLICY_MATCH, result);
  114. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  115. delete[] reinterpret_cast<char*>(policy);
  116. }
  117. TEST(PolicyEngineTest, SimpleIfNotStrMatchWild2) {
  118. PolicyRule pr(ASK_BROKER);
  119. EXPECT_TRUE(
  120. pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*.txt", CASE_SENSITIVE));
  121. PolicyGlobal* policy = MakePolicyMemory();
  122. const IpcTag kFakeService = IpcTag::NTCREATEFILE;
  123. LowLevelPolicy policyGen(policy);
  124. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  125. EXPECT_TRUE(policyGen.Done());
  126. const wchar_t* filename = nullptr;
  127. POLPARAMS_BEGIN(eval_params)
  128. POLPARAM(filename) // Argument 0
  129. POLPARAMS_END;
  130. PolicyResult result;
  131. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  132. filename = L"c:\\Microsoft\\domo.txt";
  133. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  134. EXPECT_EQ(NO_POLICY_MATCH, result);
  135. filename = L"c:\\MicroNerd\\domo.txt";
  136. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  137. EXPECT_EQ(POLICY_MATCH, result);
  138. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  139. filename = L"c:\\Microsoft\\domo.bmp";
  140. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  141. EXPECT_EQ(POLICY_MATCH, result);
  142. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  143. delete[] reinterpret_cast<char*>(policy);
  144. }
  145. TEST(PolicyEngineTest, IfNotStrMatchTwoRulesWild1) {
  146. PolicyRule pr(ASK_BROKER);
  147. EXPECT_TRUE(
  148. pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*", CASE_SENSITIVE));
  149. EXPECT_TRUE(pr.AddNumberMatch(IF, 1, 24, EQUAL));
  150. PolicyGlobal* policy = MakePolicyMemory();
  151. const IpcTag kFakeService = IpcTag::NTCREATEFILE;
  152. LowLevelPolicy policyGen(policy);
  153. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  154. EXPECT_TRUE(policyGen.Done());
  155. const wchar_t* filename = nullptr;
  156. uint32_t access = 0;
  157. POLPARAMS_BEGIN(eval_params)
  158. POLPARAM(filename) // Argument 0
  159. POLPARAM(access) // Argument 1
  160. POLPARAMS_END;
  161. PolicyResult result;
  162. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  163. filename = L"c:\\Microsoft\\domo.txt";
  164. access = 24;
  165. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  166. EXPECT_EQ(NO_POLICY_MATCH, result);
  167. filename = L"c:\\Microsoft\\domo.txt";
  168. access = 42;
  169. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  170. EXPECT_EQ(NO_POLICY_MATCH, result);
  171. filename = L"c:\\MicroNerd\\domo.txt";
  172. access = 24;
  173. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  174. EXPECT_EQ(POLICY_MATCH, result);
  175. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  176. filename = L"c:\\Micronesia\\domo.txt";
  177. access = 42;
  178. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  179. EXPECT_EQ(NO_POLICY_MATCH, result);
  180. delete[] reinterpret_cast<char*>(policy);
  181. }
  182. TEST(PolicyEngineTest, IfNotStrMatchTwoRulesWild2) {
  183. PolicyRule pr(ASK_BROKER);
  184. EXPECT_TRUE(pr.AddNumberMatch(IF, 1, 24, EQUAL));
  185. EXPECT_TRUE(
  186. pr.AddStringMatch(IF_NOT, 0, L"c:\\GoogleV?\\*.txt", CASE_SENSITIVE));
  187. EXPECT_TRUE(pr.AddNumberMatch(IF, 2, 66, EQUAL));
  188. PolicyGlobal* policy = MakePolicyMemory();
  189. const IpcTag kFakeService = IpcTag::NTCREATEFILE;
  190. LowLevelPolicy policyGen(policy);
  191. EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
  192. EXPECT_TRUE(policyGen.Done());
  193. const wchar_t* filename = nullptr;
  194. uint32_t access = 0;
  195. uint32_t sharing = 66;
  196. POLPARAMS_BEGIN(eval_params)
  197. POLPARAM(filename) // Argument 0
  198. POLPARAM(access) // Argument 1
  199. POLPARAM(sharing) // Argument 2
  200. POLPARAMS_END;
  201. PolicyResult result;
  202. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kFakeService)]);
  203. filename = L"c:\\GoogleV2\\domo.txt";
  204. access = 24;
  205. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  206. EXPECT_EQ(NO_POLICY_MATCH, result);
  207. filename = L"c:\\GoogleV2\\domo.bmp";
  208. access = 24;
  209. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  210. EXPECT_EQ(POLICY_MATCH, result);
  211. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  212. filename = L"c:\\GoogleV23\\domo.txt";
  213. access = 24;
  214. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  215. EXPECT_EQ(POLICY_MATCH, result);
  216. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  217. filename = L"c:\\GoogleV2\\domo.txt";
  218. access = 42;
  219. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  220. EXPECT_EQ(NO_POLICY_MATCH, result);
  221. filename = L"c:\\Google\\domo.txt";
  222. access = 24;
  223. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  224. EXPECT_EQ(POLICY_MATCH, result);
  225. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  226. filename = L"c:\\Micronesia\\domo.txt";
  227. access = 42;
  228. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  229. EXPECT_EQ(NO_POLICY_MATCH, result);
  230. filename = L"c:\\GoogleV2\\domo.bmp";
  231. access = 24;
  232. sharing = 0;
  233. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  234. EXPECT_EQ(NO_POLICY_MATCH, result);
  235. delete[] reinterpret_cast<char*>(policy);
  236. }
  237. // Testing one single rule in one single service. The service is made to
  238. // resemble NtCreateFile.
  239. TEST(PolicyEngineTest, OneRuleTest) {
  240. PolicyRule pr(ASK_BROKER);
  241. EXPECT_TRUE(
  242. pr.AddStringMatch(IF, 0, L"c:\\*Microsoft*\\*.txt", CASE_SENSITIVE));
  243. EXPECT_TRUE(pr.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL));
  244. EXPECT_TRUE(pr.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
  245. PolicyGlobal* policy = MakePolicyMemory();
  246. const IpcTag kNtFakeCreateFile = IpcTag::NTCREATEFILE;
  247. LowLevelPolicy policyGen(policy);
  248. EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr));
  249. EXPECT_TRUE(policyGen.Done());
  250. const wchar_t* filename = L"c:\\Documents and Settings\\Microsoft\\BLAH.txt";
  251. uint32_t creation_mode = OPEN_EXISTING;
  252. uint32_t flags = FILE_ATTRIBUTE_NORMAL;
  253. void* security_descriptor = nullptr;
  254. POLPARAMS_BEGIN(eval_params)
  255. POLPARAM(filename) // Argument 0
  256. POLPARAM(creation_mode) // Argument 1
  257. POLPARAM(flags) // Argument 2
  258. POLPARAM(security_descriptor)
  259. POLPARAMS_END;
  260. PolicyResult result;
  261. PolicyProcessor pol_ev(policy->entry[static_cast<size_t>(kNtFakeCreateFile)]);
  262. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  263. EXPECT_EQ(POLICY_MATCH, result);
  264. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  265. creation_mode = CREATE_ALWAYS;
  266. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  267. EXPECT_EQ(NO_POLICY_MATCH, result);
  268. creation_mode = OPEN_EXISTING;
  269. filename = L"c:\\Other\\Path\\Microsoft\\Another file.txt";
  270. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  271. EXPECT_EQ(POLICY_MATCH, result);
  272. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  273. filename = L"c:\\Other\\Path\\Microsoft\\Another file.txt.tmp";
  274. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  275. EXPECT_EQ(NO_POLICY_MATCH, result);
  276. flags = FILE_ATTRIBUTE_DEVICE;
  277. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  278. EXPECT_EQ(NO_POLICY_MATCH, result);
  279. filename = L"c:\\Other\\Macrosoft\\Another file.txt";
  280. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  281. EXPECT_EQ(NO_POLICY_MATCH, result);
  282. filename = L"c:\\Microsoft\\1.txt";
  283. flags = FILE_ATTRIBUTE_NORMAL;
  284. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  285. EXPECT_EQ(POLICY_MATCH, result);
  286. EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
  287. filename = L"c:\\Microsoft\\1.ttt";
  288. result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
  289. EXPECT_EQ(NO_POLICY_MATCH, result);
  290. delete[] reinterpret_cast<char*>(policy);
  291. }
  292. // Testing 3 rules in 3 services. Two of the services resemble File services.
  293. TEST(PolicyEngineTest, ThreeRulesTest) {
  294. PolicyRule pr_pipe(FAKE_SUCCESS);
  295. EXPECT_TRUE(pr_pipe.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*",
  296. CASE_INSENSITIVE));
  297. EXPECT_TRUE(pr_pipe.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
  298. EXPECT_TRUE(pr_pipe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
  299. size_t opc1 = pr_pipe.GetOpcodeCount();
  300. EXPECT_EQ(3u, opc1);
  301. PolicyRule pr_dump(ASK_BROKER);
  302. EXPECT_TRUE(pr_dump.AddStringMatch(IF, 0, L"\\\\/?/?\\*\\Crash Reports\\*",
  303. CASE_INSENSITIVE));
  304. EXPECT_TRUE(pr_dump.AddNumberMatch(IF, 1, CREATE_ALWAYS, EQUAL));
  305. EXPECT_TRUE(pr_dump.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
  306. size_t opc2 = pr_dump.GetOpcodeCount();
  307. EXPECT_EQ(4u, opc2);
  308. PolicyRule pr_winexe(SIGNAL_ALARM);
  309. EXPECT_TRUE(pr_winexe.AddStringMatch(IF, 0, L"\\\\/?/?\\C:\\Windows\\*.exe",
  310. CASE_INSENSITIVE));
  311. EXPECT_TRUE(pr_winexe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
  312. size_t opc3 = pr_winexe.GetOpcodeCount();
  313. EXPECT_EQ(3u, opc3);
  314. PolicyRule pr_adobe(GIVE_CACHED);
  315. EXPECT_TRUE(
  316. pr_adobe.AddStringMatch(IF, 0, L"c:\\adobe\\ver?.?\\", CASE_SENSITIVE));
  317. EXPECT_TRUE(pr_adobe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
  318. size_t opc4 = pr_adobe.GetOpcodeCount();
  319. EXPECT_EQ(4u, opc4);
  320. PolicyRule pr_none(GIVE_FIRST);
  321. EXPECT_TRUE(pr_none.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_READONLY, AND));
  322. EXPECT_TRUE(pr_none.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_SYSTEM, AND));
  323. size_t opc5 = pr_none.GetOpcodeCount();
  324. EXPECT_EQ(2u, opc5);
  325. PolicyGlobal* policy = MakePolicyMemory();
  326. // These do not match the real tag values.
  327. const IpcTag kNtFakeNone = static_cast<IpcTag>(4);
  328. const IpcTag kNtFakeCreateFile = static_cast<IpcTag>(5);
  329. const IpcTag kNtFakeOpenFile = static_cast<IpcTag>(6);
  330. LowLevelPolicy policyGen(policy);
  331. EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_pipe));
  332. EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_dump));
  333. EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_winexe));
  334. EXPECT_TRUE(policyGen.AddRule(kNtFakeOpenFile, &pr_adobe));
  335. EXPECT_TRUE(policyGen.AddRule(kNtFakeOpenFile, &pr_pipe));
  336. EXPECT_TRUE(policyGen.AddRule(kNtFakeNone, &pr_none));
  337. EXPECT_TRUE(policyGen.Done());
  338. // Inspect the policy structure manually.
  339. EXPECT_FALSE(policy->entry[0]);
  340. EXPECT_FALSE(policy->entry[1]);
  341. EXPECT_FALSE(policy->entry[2]);
  342. EXPECT_FALSE(policy->entry[3]);
  343. EXPECT_TRUE(policy->entry[4]); // kNtFakeNone.
  344. EXPECT_TRUE(policy->entry[5]); // kNtFakeCreateFile.
  345. EXPECT_TRUE(policy->entry[6]); // kNtFakeOpenFile.
  346. EXPECT_FALSE(policy->entry[7]);
  347. // The total per service opcode counts now must take in account one
  348. // extra opcode (action opcode) per rule.
  349. ++opc1;
  350. ++opc2;
  351. ++opc3;
  352. ++opc4;
  353. ++opc5;
  354. size_t tc1 = policy->entry[static_cast<size_t>(kNtFakeNone)]->opcode_count;
  355. size_t tc2 =
  356. policy->entry[static_cast<size_t>(kNtFakeCreateFile)]->opcode_count;
  357. size_t tc3 =
  358. policy->entry[static_cast<size_t>(kNtFakeOpenFile)]->opcode_count;
  359. EXPECT_EQ(opc5, tc1);
  360. EXPECT_EQ((opc1 + opc2 + opc3), tc2);
  361. EXPECT_EQ((opc1 + opc4), tc3);
  362. // Check the type of the first and last opcode of each service.
  363. EXPECT_EQ(
  364. OP_NUMBER_AND_MATCH,
  365. policy->entry[static_cast<size_t>(kNtFakeNone)]->opcodes[0].GetID());
  366. EXPECT_EQ(OP_ACTION, policy->entry[static_cast<size_t>(kNtFakeNone)]
  367. ->opcodes[tc1 - 1]
  368. .GetID());
  369. EXPECT_EQ(OP_WSTRING_MATCH,
  370. policy->entry[static_cast<size_t>(kNtFakeCreateFile)]
  371. ->opcodes[0]
  372. .GetID());
  373. EXPECT_EQ(OP_ACTION, policy->entry[static_cast<size_t>(kNtFakeCreateFile)]
  374. ->opcodes[tc2 - 1]
  375. .GetID());
  376. EXPECT_EQ(
  377. OP_WSTRING_MATCH,
  378. policy->entry[static_cast<size_t>(kNtFakeOpenFile)]->opcodes[0].GetID());
  379. EXPECT_EQ(OP_ACTION, policy->entry[static_cast<size_t>(kNtFakeOpenFile)]
  380. ->opcodes[tc3 - 1]
  381. .GetID());
  382. // Test the policy evaluation.
  383. const wchar_t* filename = L"";
  384. uint32_t creation_mode = OPEN_EXISTING;
  385. uint32_t flags = FILE_ATTRIBUTE_NORMAL;
  386. void* security_descriptor = nullptr;
  387. POLPARAMS_BEGIN(params)
  388. POLPARAM(filename) // Argument 0
  389. POLPARAM(creation_mode) // Argument 1
  390. POLPARAM(flags) // Argument 2
  391. POLPARAM(security_descriptor)
  392. POLPARAMS_END;
  393. PolicyResult result;
  394. PolicyProcessor eval_CreateFile(
  395. policy->entry[static_cast<size_t>(kNtFakeCreateFile)]);
  396. PolicyProcessor eval_OpenFile(
  397. policy->entry[static_cast<size_t>(kNtFakeOpenFile)]);
  398. PolicyProcessor eval_None(policy->entry[static_cast<size_t>(kNtFakeNone)]);
  399. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  400. EXPECT_EQ(NO_POLICY_MATCH, result);
  401. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  402. EXPECT_EQ(NO_POLICY_MATCH, result);
  403. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  404. EXPECT_EQ(NO_POLICY_MATCH, result);
  405. filename = L"\\\\??\\c:\\Windows\\System32\\calc.exe";
  406. flags = FILE_ATTRIBUTE_SYSTEM;
  407. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  408. EXPECT_EQ(NO_POLICY_MATCH, result);
  409. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  410. EXPECT_EQ(NO_POLICY_MATCH, result);
  411. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  412. EXPECT_EQ(NO_POLICY_MATCH, result);
  413. flags += FILE_ATTRIBUTE_READONLY;
  414. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  415. EXPECT_EQ(NO_POLICY_MATCH, result);
  416. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  417. EXPECT_EQ(POLICY_MATCH, result);
  418. EXPECT_EQ(GIVE_FIRST, eval_None.GetAction());
  419. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  420. EXPECT_EQ(NO_POLICY_MATCH, result);
  421. flags = FILE_ATTRIBUTE_NORMAL;
  422. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  423. EXPECT_EQ(POLICY_MATCH, result);
  424. EXPECT_EQ(SIGNAL_ALARM, eval_CreateFile.GetAction());
  425. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  426. EXPECT_EQ(NO_POLICY_MATCH, result);
  427. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  428. EXPECT_EQ(NO_POLICY_MATCH, result);
  429. filename = L"c:\\adobe\\ver3.2\\temp";
  430. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  431. EXPECT_EQ(NO_POLICY_MATCH, result);
  432. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  433. EXPECT_EQ(NO_POLICY_MATCH, result);
  434. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  435. EXPECT_EQ(POLICY_MATCH, result);
  436. EXPECT_EQ(GIVE_CACHED, eval_OpenFile.GetAction());
  437. filename = L"c:\\adobe\\ver3.22\\temp";
  438. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  439. EXPECT_EQ(NO_POLICY_MATCH, result);
  440. filename = L"\\\\??\\c:\\some path\\other path\\crash reports\\some path";
  441. creation_mode = CREATE_ALWAYS;
  442. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  443. EXPECT_EQ(POLICY_MATCH, result);
  444. EXPECT_EQ(ASK_BROKER, eval_CreateFile.GetAction());
  445. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  446. EXPECT_EQ(NO_POLICY_MATCH, result);
  447. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  448. EXPECT_EQ(NO_POLICY_MATCH, result);
  449. filename = L"\\\\??\\Pipe\\Chrome.12345";
  450. creation_mode = OPEN_EXISTING;
  451. result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
  452. EXPECT_EQ(POLICY_MATCH, result);
  453. EXPECT_EQ(FAKE_SUCCESS, eval_CreateFile.GetAction());
  454. result = eval_None.Evaluate(kShortEval, params, _countof(params));
  455. EXPECT_EQ(NO_POLICY_MATCH, result);
  456. result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
  457. EXPECT_EQ(POLICY_MATCH, result);
  458. EXPECT_EQ(FAKE_SUCCESS, eval_OpenFile.GetAction());
  459. delete[] reinterpret_cast<char*>(policy);
  460. }
  461. TEST(PolicyEngineTest, PolicyRuleCopyConstructorTwoStrings) {
  462. // Both pr_orig and pr_copy should allow hello.* but not *.txt files.
  463. PolicyRule pr_orig(ASK_BROKER);
  464. EXPECT_TRUE(pr_orig.AddStringMatch(IF, 0, L"hello.*", CASE_SENSITIVE));
  465. PolicyRule pr_copy(pr_orig);
  466. EXPECT_TRUE(pr_orig.AddStringMatch(IF_NOT, 0, L"*.txt", CASE_SENSITIVE));
  467. EXPECT_TRUE(pr_copy.AddStringMatch(IF_NOT, 0, L"*.txt", CASE_SENSITIVE));
  468. PolicyGlobal* policy = MakePolicyMemory();
  469. LowLevelPolicy policyGen(policy);
  470. EXPECT_TRUE(policyGen.AddRule(IpcTag::PING1, &pr_orig));
  471. EXPECT_TRUE(policyGen.AddRule(IpcTag::PING2, &pr_copy));
  472. EXPECT_TRUE(policyGen.Done());
  473. const wchar_t* name = nullptr;
  474. POLPARAMS_BEGIN(eval_params)
  475. POLPARAM(name)
  476. POLPARAMS_END;
  477. PolicyResult result;
  478. PolicyProcessor pol_ev_orig(policy->entry[1]);
  479. name = L"domo.txt";
  480. result = pol_ev_orig.Evaluate(kShortEval, eval_params, _countof(eval_params));
  481. EXPECT_EQ(NO_POLICY_MATCH, result);
  482. name = L"hello.bmp";
  483. result = pol_ev_orig.Evaluate(kShortEval, eval_params, _countof(eval_params));
  484. EXPECT_EQ(POLICY_MATCH, result);
  485. EXPECT_EQ(ASK_BROKER, pol_ev_orig.GetAction());
  486. PolicyProcessor pol_ev_copy(policy->entry[2]);
  487. name = L"domo.txt";
  488. result = pol_ev_copy.Evaluate(kShortEval, eval_params, _countof(eval_params));
  489. EXPECT_EQ(NO_POLICY_MATCH, result);
  490. name = L"hello.bmp";
  491. result = pol_ev_copy.Evaluate(kShortEval, eval_params, _countof(eval_params));
  492. EXPECT_EQ(POLICY_MATCH, result);
  493. EXPECT_EQ(ASK_BROKER, pol_ev_copy.GetAction());
  494. }
  495. TEST(PolicyEngineTest, PolicyGenDoneCalledTwice) {
  496. // The specific rules here are not important.
  497. PolicyRule pr_orig(ASK_BROKER);
  498. EXPECT_TRUE(pr_orig.AddStringMatch(IF, 0, L"hello.*", CASE_SENSITIVE));
  499. PolicyRule pr_copy(pr_orig);
  500. EXPECT_TRUE(pr_orig.AddStringMatch(IF_NOT, 0, L"*.txt", CASE_SENSITIVE));
  501. EXPECT_TRUE(pr_copy.AddStringMatch(IF_NOT, 0, L"*.txt", CASE_SENSITIVE));
  502. PolicyGlobal* policy = MakePolicyMemory();
  503. LowLevelPolicy policyGen(policy);
  504. const IpcTag tag1 = IpcTag::PING1;
  505. const IpcTag tag2 = IpcTag::PING2;
  506. EXPECT_TRUE(policyGen.AddRule(tag1, &pr_orig));
  507. EXPECT_TRUE(policyGen.AddRule(tag2, &pr_copy));
  508. EXPECT_TRUE(policyGen.Done());
  509. // Obtain opcode counts.
  510. size_t tc1 = policy->entry[static_cast<size_t>(IpcTag::PING1)]->opcode_count;
  511. size_t tc2 = policy->entry[static_cast<size_t>(IpcTag::PING2)]->opcode_count;
  512. // Call Done() again.
  513. EXPECT_TRUE(policyGen.Done());
  514. // Expect same opcode counts.
  515. EXPECT_EQ(tc1,
  516. policy->entry[static_cast<size_t>(IpcTag::PING1)]->opcode_count);
  517. EXPECT_EQ(tc2,
  518. policy->entry[static_cast<size_t>(IpcTag::PING2)]->opcode_count);
  519. // Confirm the rules work as before.
  520. const wchar_t* name = nullptr;
  521. POLPARAMS_BEGIN(eval_params)
  522. POLPARAM(name)
  523. POLPARAMS_END;
  524. PolicyResult result;
  525. PolicyProcessor pol_ev_orig(policy->entry[1]);
  526. name = L"domo.txt";
  527. result = pol_ev_orig.Evaluate(kShortEval, eval_params, _countof(eval_params));
  528. EXPECT_EQ(NO_POLICY_MATCH, result);
  529. name = L"hello.bmp";
  530. result = pol_ev_orig.Evaluate(kShortEval, eval_params, _countof(eval_params));
  531. EXPECT_EQ(POLICY_MATCH, result);
  532. EXPECT_EQ(ASK_BROKER, pol_ev_orig.GetAction());
  533. }
  534. } // namespace sandbox