summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster808@gmail.com>2019-05-06 11:36:58 -0700
committerArmin Kuster <akuster808@gmail.com>2019-05-09 17:45:13 -0700
commit8eee8727cb09a9fc14e899b4058fcd108f44a0eb (patch)
treee6cd90e7b08c098e425a8d0efbb29fd88fc9ee2e
parent5d37937f2e495147fd2a756d22c09f49773ac8ae (diff)
downloadmeta-security-8eee8727cb09a9fc14e899b4058fcd108f44a0eb.tar.gz
smack-test: add smack tests from meta-intel-iot-security
ported over smack tests Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--lib/oeqa/runtime/cases/smack.py529
-rw-r--r--recipes-mac/smack/mmap-smack-test/mmap.c7
-rw-r--r--recipes-mac/smack/mmap-smack-test_1.0.bb16
-rw-r--r--recipes-mac/smack/smack-test/notroot.py33
-rw-r--r--recipes-mac/smack/smack-test/smack_test_file_access.sh54
-rw-r--r--recipes-mac/smack/smack-test/test_privileged_change_self_label.sh18
-rw-r--r--recipes-mac/smack/smack-test/test_smack_onlycap.sh27
-rw-r--r--recipes-mac/smack/smack-test_1.0.bb21
-rw-r--r--recipes-mac/smack/tcp-smack-test/tcp_client.c111
-rw-r--r--recipes-mac/smack/tcp-smack-test/tcp_server.c118
-rw-r--r--recipes-mac/smack/tcp-smack-test/test_smack_tcp_sockets.sh108
-rw-r--r--recipes-mac/smack/tcp-smack-test_1.0.bb24
-rw-r--r--recipes-mac/smack/udp-smack-test/test_smack_udp_sockets.sh107
-rw-r--r--recipes-mac/smack/udp-smack-test/udp_client.c75
-rw-r--r--recipes-mac/smack/udp-smack-test/udp_server.c93
-rw-r--r--recipes-mac/smack/udp-smack-test_1.0.bb23
16 files changed, 1364 insertions, 0 deletions
diff --git a/lib/oeqa/runtime/cases/smack.py b/lib/oeqa/runtime/cases/smack.py
new file mode 100644
index 0000000..35e87ef
--- /dev/null
+++ b/lib/oeqa/runtime/cases/smack.py
@@ -0,0 +1,529 @@
1import unittest
2import re
3import os
4import string
5from oeqa.runtime.case import OERuntimeTestCase
6from oeqa.core.decorator.depends import OETestDepends
7from oeqa.runtime.decorator.package import OEHasPackage
8from oeqa.core.decorator.data import skipIfNotFeature
9
10MAX_LABEL_LEN = 255
11LABEL = "a" * MAX_LABEL_LEN
12
13class SmackBasicTest(OERuntimeTestCase):
14 ''' base smack test '''
15
16 @classmethod
17 def setUpClass(cls):
18 cls.smack_path = ""
19 cls.current_label = ""
20 cls.uid = 1000
21
22 @skipIfNotFeature('smack',
23 'Test requires smack to be in DISTRO_FEATURES')
24 @OEHasPackage(['smack-test'])
25 @OETestDepends(['ssh.SSHTest.test_ssh'])
26 def test_smack_basic(self):
27 status, output = self.target.run("grep smack /proc/mounts | awk '{print $2}'")
28 self.smack_path = output
29 status,output = self.target.run("cat /proc/self/attr/current")
30 self.current_label = output.strip()
31
32class SmackAccessLabel(SmackBasicTest):
33
34 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
35 def test_add_access_label(self):
36 ''' Test if chsmack can correctly set a SMACK label '''
37 filename = "/tmp/test_access_label"
38 self.target.run("touch %s" %filename)
39 status, output = self.target.run("chsmack -a %s %s" %(LABEL, filename))
40 self.assertEqual(
41 status, 0,
42 "Cannot set smack access label. "
43 "Status and output: %d %s" %(status, output))
44 status, output = self.target.run("chsmack %s" %filename)
45 self.target.run("rm %s" %filename)
46 m = re.search('(?<=access=")\S+(?=")', output)
47 if m is None:
48 self.fail("Did not find access attribute")
49 else:
50 label_retrieved = m .group(0)
51 self.assertEqual(
52 LABEL, label_retrieved,
53 "label not set correctly. expected and gotten: "
54 "%s %s" %(LABEL,label_retrieved))
55
56
57class SmackExecLabel(SmackBasicTest):
58
59 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
60 def test_add_exec_label(self):
61 '''Test if chsmack can correctly set a SMACK Exec label'''
62 filename = "/tmp/test_exec_label"
63 self.target.run("touch %s" %filename)
64 status, output = self.target.run("chsmack -e %s %s" %(LABEL, filename))
65 self.assertEqual(
66 status, 0,
67 "Cannot set smack exec label. "
68 "Status and output: %d %s" %(status, output))
69 status, output = self.target.run("chsmack %s" %filename)
70 self.target.run("rm %s" %filename)
71 m= re.search('(?<=execute=")\S+(?=")', output)
72 if m is None:
73 self.fail("Did not find execute attribute")
74 else:
75 label_retrieved = m.group(0)
76 self.assertEqual(
77 LABEL, label_retrieved,
78 "label not set correctly. expected and gotten: " +
79 "%s %s" %(LABEL,label_retrieved))
80
81
82class SmackMmapLabel(SmackBasicTest):
83
84 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
85 def test_add_mmap_label(self):
86 '''Test if chsmack can correctly set a SMACK mmap label'''
87 filename = "/tmp/test_exec_label"
88 self.target.run("touch %s" %filename)
89 status, output = self.target.run("chsmack -m %s %s" %(LABEL, filename))
90 self.assertEqual(
91 status, 0,
92 "Cannot set smack mmap label. "
93 "Status and output: %d %s" %(status, output))
94 status, output = self.target.run("chsmack %s" %filename)
95 self.target.run("rm %s" %filename)
96 m = re.search('(?<=mmap=")\S+(?=")', output)
97 if m is None:
98 self.fail("Did not find mmap attribute")
99 else:
100 label_retrieved = m.group(0)
101 self.assertEqual(
102 LABEL, label_retrieved,
103 "label not set correctly. expected and gotten: " +
104 "%s %s" %(LABEL,label_retrieved))
105
106
107class SmackTransmutable(SmackBasicTest):
108
109 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
110 def test_add_transmutable(self):
111 '''Test if chsmack can correctly set a SMACK transmutable mode'''
112
113 directory = "~/test_transmutable"
114 self.target.run("mkdir -p %s" %directory)
115 status, output = self.target.run("chsmack -t %s" %directory)
116 self.assertEqual(status, 0, "Cannot set smack transmutable. "
117 "Status and output: %d %s" %(status, output))
118 status, output = self.target.run("chsmack %s" %directory)
119 self.target.run("rmdir %s" %directory)
120 m = re.search('(?<=transmute=")\S+(?=")', output)
121 if m is None:
122 self.fail("Did not find transmute attribute")
123 else:
124 label_retrieved = m.group(0)
125 self.assertEqual(
126 "TRUE", label_retrieved,
127 "label not set correctly. expected and gotten: " +
128 "%s %s" %(LABEL,label_retrieved))
129
130
131class SmackChangeSelfLabelPrivilege(SmackBasicTest):
132
133 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
134 def test_privileged_change_self_label(self):
135 '''Test if privileged process (with CAP_MAC_ADMIN privilege)
136 can change its label.
137 '''
138
139 labelf = "/proc/self/attr/current"
140 command = "/bin/sh -c 'echo PRIVILEGED >%s; cat %s'" %(labelf, labelf)
141
142 status, output = self.target.run(
143 "notroot.py 0 %s %s" %(self.current_label, command))
144
145 self.assertIn("PRIVILEGED", output,
146 "Privilege process did not change label.Output: %s" %output)
147
148class SmackChangeSelfLabelUnprivilege(SmackBasicTest):
149
150 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
151 def test_unprivileged_change_self_label(self):
152 '''Test if unprivileged process (without CAP_MAC_ADMIN privilege)
153 cannot change its label'''
154
155 command = "/bin/sh -c 'echo %s >/proc/self/attr/current'" %LABEL
156 status, output = self.target.run(
157 "notroot.py %d %s %s"
158 %(self.uid, self.current_label, command) +
159 " 2>&1 | grep 'Operation not permitted'" )
160
161 self.assertEqual(
162 status, 0,
163 "Unprivileged process should not be able to change its label")
164
165
166class SmackChangeFileLabelPrivilege(SmackBasicTest):
167
168 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
169 def test_unprivileged_change_file_label(self):
170 '''Test if unprivileged process cannot change file labels'''
171
172 status, chsmack = self.target.run("which chsmack")
173 status, touch = self.target.run("which touch")
174 filename = "/tmp/test_unprivileged_change_file_label"
175
176 self.target.run("touch %s" % filename)
177 self.target.run("notroot.py %d %s" %(self.uid, self.current_label))
178 status, output = self.target.run(
179 "notroot.py " +
180 "%d unprivileged %s -a %s %s 2>&1 " %(self.uid, chsmack, LABEL, filename) +
181 "| grep 'Operation not permitted'" )
182
183 self.target.run("rm %s" % filename)
184 self.assertEqual( status, 0, "Unprivileged process changed label for %s" %filename)
185
186class SmackLoadRule(SmackBasicTest):
187
188 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
189 def test_load_smack_rule(self):
190 '''Test if new smack access rules can be loaded'''
191
192 # old 23 character format requires special spaces formatting
193 # 12345678901234567890123456789012345678901234567890123
194 ruleA="TheOne TheOther rwxat"
195 ruleB="TheOne TheOther r----"
196 clean="TheOne TheOther -----"
197 modeA = "rwxat"
198 modeB = "r"
199
200 status, output = self.target.run('echo -n "%s" > %s/load' %(ruleA, self.smack_path))
201 status, output = self.target.run( 'cat %s/load | grep "^TheOne" | grep " TheOther "' %self.smack_path)
202 self.assertEqual(status, 0, "Rule A was not added")
203 mode = list(filter(bool, output.split(" ")))[2].strip()
204 self.assertEqual( mode, modeA, "Mode A was not set correctly; mode: %s" %mode)
205
206 status, output = self.target.run( 'echo -n "%s" > %s/load' %(ruleB, self.smack_path))
207 status, output = self.target.run( 'cat %s/load | grep "^TheOne" | grep " TheOther "' %self.smack_path)
208 mode = list(filter(bool, output.split(" ")))[2].strip()
209 self.assertEqual( mode, modeB, "Mode B was not set correctly; mode: %s" %mode)
210
211 self.target.run('echo -n "%s" > %s/load' %(clean, self.smack_path))
212
213
214class SmackOnlycap(SmackBasicTest):
215
216 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
217 def test_smack_onlycap(self):
218 '''Test if smack onlycap label can be set
219
220 test needs to change the running label of the current process,
221 so whole test takes places on image
222 '''
223 status, output = self.target.run("sh /usr/sbin/test_smack_onlycap.sh")
224 self.assertEqual(status, 0, output)
225
226class SmackNetlabel(SmackBasicTest):
227
228 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
229 def test_smack_netlabel(self):
230
231 test_label="191.191.191.191 TheOne"
232 expected_label="191.191.191.191/32 TheOne"
233
234 status, output = self.target.run( "echo -n '%s' > %s/netlabel" %(test_label, self.smack_path))
235 self.assertEqual( status, 0, "Netlabel /32 could not be set. Output: %s" %output)
236
237 status, output = self.target.run("cat %s/netlabel" %self.smack_path)
238 self.assertIn( expected_label, output, "Did not find expected label in output: %s" %output)
239
240 test_label="253.253.253.0/24 TheOther"
241 status, output = self.target.run( "echo -n '%s' > %s/netlabel" %(test_label, self.smack_path))
242 self.assertEqual( status, 0, "Netlabel /24 could not be set. Output: %s" %output)
243
244 status, output = self.target.run("cat %s/netlabel" %self.smack_path)
245 self.assertIn(
246 test_label, output,
247 "Did not find expected label in output: %s" %output)
248
249class SmackCipso(SmackBasicTest):
250
251 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
252 def test_smack_cipso(self):
253 '''Test if smack cipso rules can be set'''
254 # 12345678901234567890123456789012345678901234567890123456
255 ruleA="TheOneA 2 0 "
256 ruleB="TheOneB 3 1 55 "
257 ruleC="TheOneC 4 2 17 33 "
258
259 status, output = self.target.run(
260 "echo -n '%s' > %s/cipso" %(ruleA, self.smack_path))
261 self.assertEqual(status, 0,
262 "Could not set cipso label A. Ouput: %s" %output)
263
264 status, output = self.target.run(
265 "cat %s/cipso | grep '^TheOneA'" %self.smack_path)
266 self.assertEqual(status, 0, "Cipso rule A was not set")
267 self.assertIn(" 2", output, "Rule A was not set correctly")
268
269 status, output = self.target.run(
270 "echo -n '%s' > %s/cipso" %(ruleB, self.smack_path))
271 self.assertEqual(status, 0,
272 "Could not set cipso label B. Ouput: %s" %output)
273
274 status, output = self.target.run(
275 "cat %s/cipso | grep '^TheOneB'" %self.smack_path)
276 self.assertEqual(status, 0, "Cipso rule B was not set")
277 self.assertIn("/55", output, "Rule B was not set correctly")
278
279 status, output = self.target.run(
280 "echo -n '%s' > %s/cipso" %(ruleC, self.smack_path))
281 self.assertEqual(
282 status, 0,
283 "Could not set cipso label C. Ouput: %s" %output)
284
285 status, output = self.target.run(
286 "cat %s/cipso | grep '^TheOneC'" %self.smack_path)
287 self.assertEqual(status, 0, "Cipso rule C was not set")
288 self.assertIn("/17,33", output, "Rule C was not set correctly")
289
290class SmackDirect(SmackBasicTest):
291
292 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
293 def test_smack_direct(self):
294 status, initial_direct = self.target.run(
295 "cat %s/direct" %self.smack_path)
296
297 test_direct="17"
298 status, output = self.target.run(
299 "echo '%s' > %s/direct" %(test_direct, self.smack_path))
300 self.assertEqual(status, 0 ,
301 "Could not set smack direct. Output: %s" %output)
302 status, new_direct = self.target.run("cat %s/direct" %self.smack_path)
303 # initial label before checking
304 status, output = self.target.run(
305 "echo '%s' > %s/direct" %(initial_direct, self.smack_path))
306 self.assertEqual(
307 test_direct, new_direct.strip(),
308 "Smack direct label does not match.")
309
310
311class SmackAmbient(SmackBasicTest):
312
313 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
314 def test_smack_ambient(self):
315 test_ambient = "test_ambient"
316 status, initial_ambient = self.target.run("cat %s/ambient" %self.smack_path)
317 status, output = self.target.run(
318 "echo '%s' > %s/ambient" %(test_ambient, self.smack_path))
319 self.assertEqual(status, 0,
320 "Could not set smack ambient. Output: %s" %output)
321
322 status, output = self.target.run("cat %s/ambient" %self.smack_path)
323 # Filter '\x00', which is sometimes added to the ambient label
324 new_ambient = ''.join(filter(lambda x: x in string.printable, output))
325 initial_ambient = ''.join(filter(lambda x: x in string.printable, initial_ambient))
326 status, output = self.target.run(
327 "echo '%s' > %s/ambient" %(initial_ambient, self.smack_path))
328 self.assertEqual(
329 test_ambient, new_ambient.strip(),
330 "Ambient label does not match")
331
332
333class SmackloadBinary(SmackBasicTest):
334
335 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
336 def test_smackload(self):
337 '''Test if smackload command works'''
338 rule="testobject testsubject rwx"
339
340 status, output = self.target.run("echo -n '%s' > /tmp/rules" %rule)
341 status, output = self.target.run("smackload /tmp/rules")
342 self.assertEqual( status, 0, "Smackload failed to load rule. Output: %s" %output)
343
344 status, output = self.target.run( "cat %s/load | grep '%s'" %(self.smack_path, rule))
345 self.assertEqual(status, 0, "Smackload rule was loaded correctly")
346
347
348class SmackcipsoBinary(SmackBasicTest):
349
350 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
351 def test_smackcipso(self):
352 '''Test if smackcipso command works'''
353 # 12345678901234567890123456789012345678901234567890123456
354 rule="cipsolabel 2 2 "
355
356 status, output = self.target.run("echo '%s' | smackcipso" %rule)
357 self.assertEqual( status, 0, "Smackcipso failed to load rule. Output: %s" %output)
358
359 status, output = self.target.run(
360 "cat %s/cipso | grep 'cipsolabel'" %self.smack_path)
361 self.assertEqual(status, 0, "smackcipso rule was loaded correctly")
362 self.assertIn( "2/2", output, "Rule was not set correctly. Got: %s" %output)
363
364
365class SmackEnforceFileAccess(SmackBasicTest):
366
367 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
368 def test_smack_enforce_file_access(self):
369 '''Test if smack file access is enforced (rwx)
370
371 test needs to change the running label of the current process,
372 so whole test takes places on image
373 '''
374 status, output = self.target.run("sh /usr/sbin/smack_test_file_access.sh")
375 self.assertEqual(status, 0, output)
376
377
378class SmackEnforceMmap(SmackBasicTest):
379
380 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
381 def test_smack_mmap_enforced(self):
382 '''Test if smack mmap access is enforced'''
383 raise unittest.SkipTest("Depends on mmap_test, which was removed from the layer while investigating its license.")
384
385 # 12345678901234567890123456789012345678901234567890123456
386 delr1="mmap_label mmap_test_label1 -----"
387 delr2="mmap_label mmap_test_label2 -----"
388 delr3="mmap_file_label mmap_test_label1 -----"
389 delr4="mmap_file_label mmap_test_label2 -----"
390
391 RuleA="mmap_label mmap_test_label1 rw---"
392 RuleB="mmap_label mmap_test_label2 r--at"
393 RuleC="mmap_file_label mmap_test_label1 rw---"
394 RuleD="mmap_file_label mmap_test_label2 rwxat"
395
396 mmap_label="mmap_label"
397 file_label="mmap_file_label"
398 test_file = "/usr/sbin/smack_test_mmap"
399 mmap_exe = "/tmp/mmap_test"
400 status, echo = self.target.run("which echo")
401 status, output = self.target.run(
402 "notroot.py %d %s %s 'test' > %s" \
403 %(self.uid, self.current_label, echo, test_file))
404 status, output = self.target.run("ls %s" %test_file)
405 self.assertEqual(status, 0, "Could not create mmap test file")
406 self.target.run("chsmack -m %s %s" %(file_label, test_file))
407 self.target.run("chsmack -e %s %s" %(mmap_label, mmap_exe))
408
409 # test with no rules with mmap label or exec label as subject
410 # access should be granted
411 self.target.run('echo -n "%s" > %s/load' %(delr1, self.smack_path))
412 self.target.run('echo -n "%s" > %s/load' %(delr2, self.smack_path))
413 self.target.run('echo -n "%s" > %s/load' %(delr3, self.smack_path))
414 self.target.run('echo -n "%s" > %s/load' %(delr4, self.smack_path))
415 status, output = self.target.run("%s %s 0 2" % (mmap_exe, test_file))
416 self.assertEqual(
417 status, 0,
418 "Should have mmap access without rules. Output: %s" %output)
419
420 # add rules that do not match access required
421 self.target.run('echo -n "%s" > %s/load' %(RuleA, self.smack_path))
422 self.target.run('echo -n "%s" > %s/load' %(RuleB, self.smack_path))
423 status, output = self.target.run("%s %s 0 2" % (mmap_exe, test_file))
424 self.assertNotEqual(
425 status, 0,
426 "Should not have mmap access with unmatching rules. " +
427 "Output: %s" %output)
428 self.assertIn(
429 "Permission denied", output,
430 "Mmap access should be denied with unmatching rules")
431
432 # add rule to match only partially (one way)
433 self.target.run('echo -n "%s" > %s/load' %(RuleC, self.smack_path))
434 status, output = self.target.run("%s %s 0 2" %(mmap_exe, test_file))
435 self.assertNotEqual(
436 status, 0,
437 "Should not have mmap access with partial matching rules. " +
438 "Output: %s" %output)
439 self.assertIn(
440 "Permission denied", output,
441 "Mmap access should be denied with partial matching rules")
442
443 # add rule to match fully
444 self.target.run('echo -n "%s" > %s/load' %(RuleD, self.smack_path))
445 status, output = self.target.run("%s %s 0 2" %(mmap_exe, test_file))
446 self.assertEqual(
447 status, 0,
448 "Should have mmap access with full matching rules." +
449 "Output: %s" %output)
450
451
452class SmackEnforceTransmutable(SmackBasicTest):
453
454 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
455 def test_smack_transmute_dir(self):
456 '''Test if smack transmute attribute works
457
458 test needs to change the running label of the current process,
459 so whole test takes places on image
460 '''
461 test_dir = "/tmp/smack_transmute_dir"
462 label="transmute_label"
463 status, initial_label = self.target.run("cat /proc/self/attr/current")
464
465 self.target.run("mkdir -p %s" % test_dir)
466 self.target.run("chsmack -a %s %s" % (label, test_dir))
467 self.target.run("chsmack -t %s" % test_dir)
468 self.target.run("echo -n '%s %s rwxat' | smackload" %(initial_label, label) )
469
470 self.target.run("touch %s/test" % test_dir)
471 status, output = self.target.run("chsmack %s/test" % test_dir)
472 self.assertIn( 'access="%s"' %label, output,
473 "Did not get expected label. Output: %s" % output)
474
475
476class SmackTcpSockets(SmackBasicTest):
477
478 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
479 def test_smack_tcp_sockets(self):
480 '''Test if smack is enforced on tcp sockets
481
482 whole test takes places on image, depends on tcp_server/tcp_client'''
483
484 status, output = self.target.run("sh /usr/sbin/test_smack_tcp_sockets.sh")
485 self.assertEqual(status, 0, output)
486
487
488class SmackUdpSockets(SmackBasicTest):
489
490 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
491 def test_smack_udp_sockets(self):
492 '''Test if smack is enforced on udp sockets
493
494 whole test takes places on image, depends on udp_server/udp_client'''
495
496 status, output = self.target.run("sh /usr/sbin/test_smack_udp_sockets.sh")
497 self.assertEqual(status, 0, output)
498
499
500class SmackFileLabels(SmackBasicTest):
501
502 @OETestDepends(['smack.SmackBasicTest.test_smack_basic'])
503 def test_smack_labels(self):
504 '''Check for correct Smack labels.'''
505 expected = '''
506/tmp/ access="*"
507/etc/ access="System::Shared" transmute="TRUE"
508/etc/passwd access="System::Shared"
509/etc/terminfo access="System::Shared" transmute="TRUE"
510/etc/skel/ access="System::Shared" transmute="TRUE"
511/etc/skel/.profile access="System::Shared"
512/var/log/ access="System::Log" transmute="TRUE"
513/var/tmp/ access="*"
514'''
515 files = ' '.join([x.split()[0] for x in expected.split('\n') if x])
516 files_wildcard = ' '.join([x + '/*' for x in files.split()])
517 # Auxiliary information.
518 status, output = self.target.run(
519 'set -x; mount; ls -l -d %s; find %s | xargs ls -d -l; find %s | xargs chsmack' % (
520 ' '.join([x.rstrip('/') for x in files.split()]), files, files
521 )
522 )
523 msg = "File status:\n" + output
524 status, output = self.target.run('chsmack %s' % files)
525 self.assertEqual(
526 status, 0, msg="status and output: %s and %s\n%s" % (status,output, msg))
527 self.longMessage = True
528 self.maxDiff = None
529 self.assertEqual(output.strip().split('\n'), expected.strip().split('\n'), msg=msg)
diff --git a/recipes-mac/smack/mmap-smack-test/mmap.c b/recipes-mac/smack/mmap-smack-test/mmap.c
new file mode 100644
index 0000000..f358d27
--- /dev/null
+++ b/recipes-mac/smack/mmap-smack-test/mmap.c
@@ -0,0 +1,7 @@
1#include <stdio.h>
2
3int main(int argc, char **argv)
4{
5 printf("Original test program removed while investigating its license.\n");
6 return 1;
7}
diff --git a/recipes-mac/smack/mmap-smack-test_1.0.bb b/recipes-mac/smack/mmap-smack-test_1.0.bb
new file mode 100644
index 0000000..9d11509
--- /dev/null
+++ b/recipes-mac/smack/mmap-smack-test_1.0.bb
@@ -0,0 +1,16 @@
1SUMMARY = "Mmap binary used to test smack mmap attribute"
2DESCRIPTION = "Mmap binary used to test smack mmap attribute"
3LICENSE = "MIT"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
5
6SRC_URI = "file://mmap.c"
7
8S = "${WORKDIR}"
9do_compile() {
10 ${CC} mmap.c ${LDFLAGS} -o mmap_test
11}
12
13do_install() {
14 install -d ${D}${bindir}
15 install -m 0755 mmap_test ${D}${bindir}
16}
diff --git a/recipes-mac/smack/smack-test/notroot.py b/recipes-mac/smack/smack-test/notroot.py
new file mode 100644
index 0000000..f0eb0b5
--- /dev/null
+++ b/recipes-mac/smack/smack-test/notroot.py
@@ -0,0 +1,33 @@
1#!/usr/bin/env python
2#
3# Script used for running executables with custom labels, as well as custom uid/gid
4# Process label is changed by writing to /proc/self/attr/curent
5#
6# Script expects user id and group id to exist, and be the same.
7#
8# From adduser manual:
9# """By default, each user in Debian GNU/Linux is given a corresponding group
10# with the same name. """
11#
12# Usage: root@desk:~# python notroot.py <uid> <label> <full_path_to_executable> [arguments ..]
13# eg: python notroot.py 1000 User::Label /bin/ping -c 3 192.168.1.1
14#
15# Author: Alexandru Cornea <alexandru.cornea@intel.com>
16import os
17import sys
18
19try:
20 uid = int(sys.argv[1])
21 sys.argv.pop(1)
22 label = sys.argv[1]
23 sys.argv.pop(1)
24 open("/proc/self/attr/current", "w").write(label)
25 path=sys.argv[1]
26 sys.argv.pop(0)
27 os.setgid(uid)
28 os.setuid(uid)
29 os.execv(path,sys.argv)
30
31except Exception,e:
32 print e.message
33 sys.exit(1)
diff --git a/recipes-mac/smack/smack-test/smack_test_file_access.sh b/recipes-mac/smack/smack-test/smack_test_file_access.sh
new file mode 100644
index 0000000..5a0ce84
--- /dev/null
+++ b/recipes-mac/smack/smack-test/smack_test_file_access.sh
@@ -0,0 +1,54 @@
1#!/bin/sh
2
3SMACK_PATH=`grep smack /proc/mounts | awk '{print $2}' `
4RC=0
5TMP="/tmp"
6test_file=$TMP/smack_test_access_file
7CAT=`which cat`
8ECHO=`which echo`
9uid=1000
10initial_label=`cat /proc/self/attr/current`
11python $TMP/notroot.py $uid "TheOther" $ECHO 'TEST' > $test_file
12chsmack -a "TheOther" $test_file
13
14# 12345678901234567890123456789012345678901234567890123456
15delrule="TheOne TheOther -----"
16rule_ro="TheOne TheOther r----"
17
18# Remove pre-existent rules for "TheOne TheOther <access>"
19echo -n "$delrule" > $SMACK_PATH/load
20python $TMP/notroot.py $uid "TheOne" $CAT $test_file 2>&1 1>/dev/null | grep -q "Permission denied" || RC=$?
21if [ $RC -ne 0 ]; then
22 echo "Process with different label than the test file and no read access on it can read it"
23 exit $RC
24fi
25
26# adding read access
27echo -n "$rule_ro" > $SMACK_PATH/load
28python $TMP/notroot.py $uid "TheOne" $CAT $test_file | grep -q "TEST" || RC=$?
29if [ $RC -ne 0 ]; then
30 echo "Process with different label than the test file but with read access on it cannot read it"
31 exit $RC
32fi
33
34# Remove pre-existent rules for "TheOne TheOther <access>"
35echo -n "$delrule" > $SMACK_PATH/load
36# changing label of test file to *
37# according to SMACK documentation, read access on a * object is always permitted
38chsmack -a '*' $test_file
39python $TMP/notroot.py $uid "TheOne" $CAT $test_file | grep -q "TEST" || RC=$?
40if [ $RC -ne 0 ]; then
41 echo "Process cannot read file with * label"
42 exit $RC
43fi
44
45# changing subject label to *
46# according to SMACK documentation, every access requested by a star labeled subject is rejected
47TOUCH=`which touch`
48python $TMP/notroot.py $uid '*' $TOUCH $TMP/test_file_2
49ls -la $TMP/test_file_2 2>&1 | grep -q 'No such file or directory' || RC=$?
50if [ $RC -ne 0 ];then
51 echo "Process with label '*' should not have any access"
52 exit $RC
53fi
54exit 0
diff --git a/recipes-mac/smack/smack-test/test_privileged_change_self_label.sh b/recipes-mac/smack/smack-test/test_privileged_change_self_label.sh
new file mode 100644
index 0000000..26d9e9d
--- /dev/null
+++ b/recipes-mac/smack/smack-test/test_privileged_change_self_label.sh
@@ -0,0 +1,18 @@
1#!/bin/sh
2
3initial_label=`cat /proc/self/attr/current 2>/dev/null`
4modified_label="test_label"
5
6echo "$modified_label" >/proc/self/attr/current 2>/dev/null
7
8new_label=`cat /proc/self/attr/current 2>/dev/null`
9
10if [ "$new_label" != "$modified_label" ]; then
11 # restore proper label
12 echo $initial_label >/proc/self/attr/current
13 echo "Privileged process could not change its label"
14 exit 1
15fi
16
17echo "$initial_label" >/proc/self/attr/current 2>/dev/null
18exit 0 \ No newline at end of file
diff --git a/recipes-mac/smack/smack-test/test_smack_onlycap.sh b/recipes-mac/smack/smack-test/test_smack_onlycap.sh
new file mode 100644
index 0000000..1c4a93a
--- /dev/null
+++ b/recipes-mac/smack/smack-test/test_smack_onlycap.sh
@@ -0,0 +1,27 @@
1#!/bin/sh
2RC=0
3SMACK_PATH=`grep smack /proc/mounts | awk '{print $2}'`
4test_label="test_label"
5onlycap_initial=`cat $SMACK_PATH/onlycap`
6smack_initial=`cat /proc/self/attr/current`
7
8# need to set out label to be the same as onlycap, otherwise we lose our smack privileges
9# even if we are root
10echo "$test_label" > /proc/self/attr/current
11
12echo "$test_label" > $SMACK_PATH/onlycap || RC=$?
13if [ $RC -ne 0 ]; then
14 echo "Onlycap label could not be set"
15 return $RC
16fi
17
18if [ `cat $SMACK_PATH/onlycap` != "$test_label" ]; then
19 echo "Onlycap label was not set correctly."
20 return 1
21fi
22
23# resetting original onlycap label
24echo "$onlycap_initial" > $SMACK_PATH/onlycap 2>/dev/null
25
26# resetting our initial's process label
27echo "$smack_initial" > /proc/self/attr/current
diff --git a/recipes-mac/smack/smack-test_1.0.bb b/recipes-mac/smack/smack-test_1.0.bb
new file mode 100644
index 0000000..7cf8f2e
--- /dev/null
+++ b/recipes-mac/smack/smack-test_1.0.bb
@@ -0,0 +1,21 @@
1SUMMARY = "Smack test scripts"
2DESCRIPTION = "Smack scripts"
3LICENSE = "MIT"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
5
6SRC_URI = " \
7 file://notroot.py \
8 file://smack_test_file_access.sh \
9 file://test_privileged_change_self_label.sh \
10 file://test_smack_onlycap.sh \
11"
12
13S = "${WORKDIR}"
14
15do_install() {
16 install -d ${D}${sbindir}
17 install -m 0755 notroot.py ${D}${sbindir}
18 install -m 0755 *.sh ${D}${sbindir}
19}
20
21RDEPENDS_${PN} = "smack python mmap-smack-test tcp-smack-test udp-smack-test"
diff --git a/recipes-mac/smack/tcp-smack-test/tcp_client.c b/recipes-mac/smack/tcp-smack-test/tcp_client.c
new file mode 100644
index 0000000..185f973
--- /dev/null
+++ b/recipes-mac/smack/tcp-smack-test/tcp_client.c
@@ -0,0 +1,111 @@
1// (C) Copyright 2015 Intel Corporation
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20#include <stdio.h>
21#include <sys/socket.h>
22#include <sys/types.h>
23#include <errno.h>
24#include <netinet/in.h>
25#include <unistd.h>
26#include <netdb.h>
27#include <string.h>
28#include <sys/xattr.h>
29
30int main(int argc, char* argv[])
31{
32
33 int sock;
34 char message[255] = "hello";
35 struct sockaddr_in server_addr;
36 char* label_in;
37 char* label_out;
38 char* attr_out = "security.SMACK64IPOUT";
39 char* attr_in = "security.SMACK64IPIN";
40 char out[256];
41 int port;
42
43 struct timeval timeout;
44 timeout.tv_sec = 15;
45 timeout.tv_usec = 0;
46
47 struct hostent* host = gethostbyname("localhost");
48
49 if (argc != 4)
50 {
51 perror("Client: Arguments missing, please provide socket labels");
52 return 2;
53 }
54
55 port = atoi(argv[1]);
56 label_in = argv[2];
57 label_out = argv[3];
58
59 if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
60 {
61 perror("Client: Socket failure");
62 return 2;
63 }
64
65
66 if(fsetxattr(sock, attr_out, label_out, strlen(label_out), 0) < 0)
67 {
68 perror("Client: Unable to set attribute SMACK64IPOUT");
69 return 2;
70 }
71
72 if(fsetxattr(sock, attr_in, label_in, strlen(label_in), 0) < 0)
73 {
74 perror("Client: Unable to set attribute SMACK64IPIN");
75 return 2;
76 }
77
78 server_addr.sin_family = AF_INET;
79 server_addr.sin_port = htons(port);
80 bcopy((char*) host->h_addr, (char*) &server_addr.sin_addr.s_addr,host->h_length);
81 bzero(&(server_addr.sin_zero),8);
82
83 if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0)
84 {
85 perror("Client: Set timeout failed\n");
86 return 2;
87 }
88
89 if (connect(sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
90 {
91 perror("Client: Connection failure");
92 close(sock);
93 return 1;
94 }
95
96
97 if(write(sock, message, strlen(message)) < 0)
98 {
99 perror("Client: Error sending data\n");
100 close(sock);
101 return 1;
102 }
103 close(sock);
104 return 0;
105}
106
107
108
109
110
111
diff --git a/recipes-mac/smack/tcp-smack-test/tcp_server.c b/recipes-mac/smack/tcp-smack-test/tcp_server.c
new file mode 100644
index 0000000..9285dc6
--- /dev/null
+++ b/recipes-mac/smack/tcp-smack-test/tcp_server.c
@@ -0,0 +1,118 @@
1// (C) Copyright 2015 Intel Corporation
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20#include <stdio.h>
21#include <sys/socket.h>
22#include <sys/types.h>
23#include <errno.h>
24#include <netinet/in.h>
25#include <unistd.h>
26#include <string.h>
27
28int main(int argc, char* argv[])
29{
30
31 int sock;
32 int clientsock;
33 char message[255];
34 socklen_t client_length;
35 struct sockaddr_in server_addr, client_addr;
36 char* label_in;
37 char* attr_in = "security.SMACK64IPIN";
38 int port;
39
40 struct timeval timeout;
41 timeout.tv_sec = 15;
42 timeout.tv_usec = 0;
43
44 if (argc != 3)
45 {
46 perror("Server: Argument missing please provide port and label for SMACK64IPIN");
47 return 2;
48 }
49
50 port = atoi(argv[1]);
51 label_in = argv[2];
52 bzero(message,255);
53
54
55 if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
56 {
57 perror("Server: Socket failure");
58 return 2;
59 }
60
61
62 if(fsetxattr(sock, attr_in, label_in, strlen(label_in),0) < 0)
63 {
64 perror("Server: Unable to set attribute ipin 2");
65 return 2;
66 }
67
68 server_addr.sin_family = AF_INET;
69 server_addr.sin_port = htons(port);
70 server_addr.sin_addr.s_addr = INADDR_ANY;
71 bzero(&(server_addr.sin_zero),8);
72
73 if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
74 {
75 perror("Server: Set timeout failed\n");
76 return 2;
77 }
78
79 if(bind(sock, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0)
80 {
81 perror("Server: Bind failure ");
82 return 2;
83 }
84
85 listen(sock, 1);
86 client_length = sizeof(client_addr);
87
88 clientsock = accept(sock,(struct sockaddr*) &client_addr, &client_length);
89
90 if (clientsock < 0)
91 {
92 perror("Server: Connection failed");
93 close(sock);
94 return 1;
95 }
96
97
98 if(fsetxattr(clientsock, "security.SMACK64IPIN", label_in, strlen(label_in),0) < 0)
99 {
100 perror(" Server: Unable to set attribute ipin 2");
101 close(sock);
102 return 2;
103 }
104
105 if(read(clientsock, message, 254) < 0)
106 {
107 perror("Server: Error when reading from socket");
108 close(clientsock);
109 close(sock);
110 return 1;
111 }
112
113
114 close(clientsock);
115 close(sock);
116
117 return 0;
118}
diff --git a/recipes-mac/smack/tcp-smack-test/test_smack_tcp_sockets.sh b/recipes-mac/smack/tcp-smack-test/test_smack_tcp_sockets.sh
new file mode 100644
index 0000000..ed18f23
--- /dev/null
+++ b/recipes-mac/smack/tcp-smack-test/test_smack_tcp_sockets.sh
@@ -0,0 +1,108 @@
1#!/bin/sh
2RC=0
3test_file=/tmp/smack_socket_tcp
4SMACK_PATH=`grep smack /proc/mounts | awk '{print $2}' `
5# make sure no access is granted
6# 12345678901234567890123456789012345678901234567890123456
7echo -n "label1 label2 -----" > $SMACK_PATH/load
8
9tcp_server=`which tcp_server`
10if [ -z $tcp_server ]; then
11 if [ -f "/tmp/tcp_server" ]; then
12 tcp_server="/tmp/tcp_server"
13 else
14 echo "tcp_server binary not found"
15 exit 1
16 fi
17fi
18tcp_client=`which tcp_client`
19if [ -z $tcp_client ]; then
20 if [ -f "/tmp/tcp_client" ]; then
21 tcp_client="/tmp/tcp_client"
22 else
23 echo "tcp_client binary not found"
24 exit 1
25 fi
26fi
27
28# checking access for sockets with different labels
29$tcp_server 50016 label1 &>/dev/null &
30server_pid=$!
31sleep 2
32$tcp_client 50016 label2 label1 &>/dev/null &
33client_pid=$!
34
35wait $server_pid
36server_rv=$?
37wait $client_pid
38client_rv=$?
39
40if [ $server_rv -eq 0 -o $client_rv -eq 0 ]; then
41 echo "Sockets with different labels should not communicate on tcp"
42 exit 1
43fi
44
45# granting access between different labels
46# 12345678901234567890123456789012345678901234567890123456
47echo -n "label1 label2 rw---" > $SMACK_PATH/load
48# checking access for sockets with different labels, but having a rule granting rw
49$tcp_server 50017 label1 2>$test_file &
50server_pid=$!
51sleep 1
52$tcp_client 50017 label2 label1 2>$test_file &
53client_pid=$!
54wait $server_pid
55server_rv=$?
56wait $client_pid
57client_rv=$?
58if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
59 echo "Sockets with different labels, but having rw access, should communicate on tcp"
60 exit 1
61fi
62
63# checking access for sockets with the same label
64$tcp_server 50018 label1 2>$test_file &
65server_pid=$!
66sleep 1
67$tcp_client 50018 label1 label1 2>$test_file &
68client_pid=$!
69wait $server_pid
70server_rv=$?
71wait $client_pid
72client_rv=$?
73if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
74 echo "Sockets with same labels should communicate on tcp"
75 exit 1
76fi
77
78# checking access on socket labeled star (*)
79# should always be permitted
80$tcp_server 50019 \* 2>$test_file &
81server_pid=$!
82sleep 1
83$tcp_client 50019 label1 label1 2>$test_file &
84client_pid=$!
85wait $server_pid
86server_rv=$?
87wait $client_pid
88client_rv=$?
89if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
90 echo "Should have access on tcp socket labeled star (*)"
91 exit 1
92fi
93
94# checking access from socket labeled star (*)
95# all access from subject star should be denied
96$tcp_server 50020 label1 2>$test_file &
97server_pid=$!
98sleep 1
99$tcp_client 50020 label1 \* 2>$test_file &
100client_pid=$!
101wait $server_pid
102server_rv=$?
103wait $client_pid
104client_rv=$?
105if [ $server_rv -eq 0 -o $client_rv -eq 0 ]; then
106 echo "Socket labeled star should not have access to any tcp socket"
107 exit 1
108fi
diff --git a/recipes-mac/smack/tcp-smack-test_1.0.bb b/recipes-mac/smack/tcp-smack-test_1.0.bb
new file mode 100644
index 0000000..d2b3f6b
--- /dev/null
+++ b/recipes-mac/smack/tcp-smack-test_1.0.bb
@@ -0,0 +1,24 @@
1SUMMARY = "Binary used to test smack tcp sockets"
2DESCRIPTION = "Server and client binaries used to test smack attributes on TCP sockets"
3LICENSE = "MIT"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
5
6SRC_URI = "file://tcp_server.c \
7 file://tcp_client.c \
8 file://test_smack_tcp_sockets.sh \
9"
10
11S = "${WORKDIR}"
12
13do_compile() {
14 ${CC} tcp_client.c ${LDFLAGS} -o tcp_client
15 ${CC} tcp_server.c ${LDFLAGS} -o tcp_server
16}
17
18do_install() {
19 install -d ${D}${bindir}
20 install -d ${D}${sbindir}
21 install -m 0755 tcp_server ${D}${bindir}
22 install -m 0755 tcp_client ${D}${bindir}
23 install -m 0755 test_smack_tcp_sockets.sh ${D}${sbindir}
24}
diff --git a/recipes-mac/smack/udp-smack-test/test_smack_udp_sockets.sh b/recipes-mac/smack/udp-smack-test/test_smack_udp_sockets.sh
new file mode 100644
index 0000000..419ab9f
--- /dev/null
+++ b/recipes-mac/smack/udp-smack-test/test_smack_udp_sockets.sh
@@ -0,0 +1,107 @@
1#!/bin/sh
2RC=0
3test_file="/tmp/smack_socket_udp"
4SMACK_PATH=`grep smack /proc/mounts | awk '{print $2}' `
5
6udp_server=`which udp_server`
7if [ -z $udp_server ]; then
8 if [ -f "/tmp/udp_server" ]; then
9 udp_server="/tmp/udp_server"
10 else
11 echo "udp_server binary not found"
12 exit 1
13 fi
14fi
15udp_client=`which udp_client`
16if [ -z $udp_client ]; then
17 if [ -f "/tmp/udp_client" ]; then
18 udp_client="/tmp/udp_client"
19 else
20 echo "udp_client binary not found"
21 exit 1
22 fi
23fi
24
25# make sure no access is granted
26# 12345678901234567890123456789012345678901234567890123456
27echo -n "label1 label2 -----" > $SMACK_PATH/load
28
29# checking access for sockets with different labels
30$udp_server 50021 label2 2>$test_file &
31server_pid=$!
32sleep 1
33$udp_client 50021 label1 2>$test_file &
34client_pid=$!
35wait $server_pid
36server_rv=$?
37wait $client_pid
38client_rv=$?
39if [ $server_rv -eq 0 ]; then
40 echo "Sockets with different labels should not communicate on udp"
41 exit 1
42fi
43
44# granting access between different labels
45# 12345678901234567890123456789012345678901234567890123456
46echo -n "label1 label2 rw---" > $SMACK_PATH/load
47# checking access for sockets with different labels, but having a rule granting rw
48$udp_server 50022 label2 2>$test_file &
49server_pid=$!
50sleep 1
51$udp_client 50022 label1 2>$test_file &
52client_pid=$!
53wait $server_pid
54server_rv=$?
55wait $client_pid
56client_rv=$?
57if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
58 echo "Sockets with different labels, but having rw access, should communicate on udp"
59 exit 1
60fi
61
62# checking access for sockets with the same label
63$udp_server 50023 label1 &
64server_pid=$!
65sleep 1
66$udp_client 50023 label1 2>$test_file &
67client_pid=$!
68wait $server_pid
69server_rv=$?
70wait $client_pid
71client_rv=$?
72if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
73 echo "Sockets with same labels should communicate on udp"
74 exit 1
75fi
76
77# checking access on socket labeled star (*)
78# should always be permitted
79$udp_server 50024 \* 2>$test_file &
80server_pid=$!
81sleep 1
82$udp_client 50024 label1 2>$test_file &
83client_pid=$!
84wait $server_pid
85server_rv=$?
86wait $client_pid
87client_rv=$?
88if [ $server_rv -ne 0 -o $client_rv -ne 0 ]; then
89 echo "Should have access on udp socket labeled star (*)"
90 exit 1
91fi
92
93# checking access from socket labeled star (*)
94# all access from subject star should be denied
95$udp_server 50025 label1 2>$test_file &
96server_pid=$!
97sleep 1
98$udp_client 50025 \* 2>$test_file &
99client_pid=$!
100wait $server_pid
101server_rv=$?
102wait $client_pid
103client_rv=$?
104if [ $server_rv -eq 0 ]; then
105 echo "Socket labeled star should not have access to any udp socket"
106 exit 1
107fi
diff --git a/recipes-mac/smack/udp-smack-test/udp_client.c b/recipes-mac/smack/udp-smack-test/udp_client.c
new file mode 100644
index 0000000..4d3afbe
--- /dev/null
+++ b/recipes-mac/smack/udp-smack-test/udp_client.c
@@ -0,0 +1,75 @@
1// (C) Copyright 2015 Intel Corporation
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20#include <sys/socket.h>
21#include <stdio.h>
22#include <netinet/in.h>
23#include <netdb.h>
24#include <string.h>
25
26int main(int argc, char* argv[])
27{
28 char* message = "hello";
29 int sock, ret;
30 struct sockaddr_in server_addr;
31 struct hostent* host = gethostbyname("localhost");
32 char* label;
33 char* attr = "security.SMACK64IPOUT";
34 int port;
35 if (argc != 3)
36 {
37 perror("Client: Argument missing, please provide port and label for SMACK64IPOUT");
38 return 2;
39 }
40
41 port = atoi(argv[1]);
42 label = argv[2];
43 sock = socket(AF_INET, SOCK_DGRAM,0);
44 if(sock < 0)
45 {
46 perror("Client: Socket failure");
47 return 2;
48 }
49
50
51 if(fsetxattr(sock, attr, label, strlen(label),0) < 0)
52 {
53 perror("Client: Unable to set attribute ");
54 return 2;
55 }
56
57
58 server_addr.sin_family = AF_INET;
59 server_addr.sin_port = htons(port);
60 bcopy((char*) host->h_addr, (char*) &server_addr.sin_addr.s_addr,host->h_length);
61 bzero(&(server_addr.sin_zero),8);
62
63 ret = sendto(sock, message, strlen(message),0,(const struct sockaddr*)&server_addr,
64 sizeof(struct sockaddr_in));
65
66 close(sock);
67 if(ret < 0)
68 {
69 perror("Client: Error sending message\n");
70 return 1;
71 }
72
73 return 0;
74}
75
diff --git a/recipes-mac/smack/udp-smack-test/udp_server.c b/recipes-mac/smack/udp-smack-test/udp_server.c
new file mode 100644
index 0000000..cbab71e
--- /dev/null
+++ b/recipes-mac/smack/udp-smack-test/udp_server.c
@@ -0,0 +1,93 @@
1// (C) Copyright 2015 Intel Corporation
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20#include <sys/socket.h>
21#include <stdio.h>
22#include <netinet/in.h>
23#include <netdb.h>
24#include <string.h>
25
26int main(int argc, char* argv[])
27{
28 int sock,ret;
29 struct sockaddr_in server_addr, client_addr;
30 socklen_t len;
31 char message[5];
32 char* label;
33 char* attr = "security.SMACK64IPIN";
34 int port;
35
36 if(argc != 3)
37 {
38 perror("Server: Argument missing, please provide port and label for SMACK64IPIN");
39 return 2;
40 }
41
42 port = atoi(argv[1]);
43 label = argv[2];
44
45 struct timeval timeout;
46 timeout.tv_sec = 15;
47 timeout.tv_usec = 0;
48
49 sock = socket(AF_INET,SOCK_DGRAM,0);
50 if(sock < 0)
51 {
52 perror("Server: Socket error");
53 return 2;
54 }
55
56
57 if(fsetxattr(sock, attr, label, strlen(label), 0) < 0)
58 {
59 perror("Server: Unable to set attribute ");
60 return 2;
61 }
62
63 server_addr.sin_family = AF_INET;
64 server_addr.sin_port = htons(port);
65 server_addr.sin_addr.s_addr = INADDR_ANY;
66 bzero(&(server_addr.sin_zero),8);
67
68
69 if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
70 {
71 perror("Server: Set timeout failed\n");
72 return 2;
73 }
74
75 if(bind(sock, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0)
76 {
77 perror("Server: Bind failure");
78 return 2;
79 }
80
81 len = sizeof(client_addr);
82 ret = recvfrom(sock, message, sizeof(message), 0, (struct sockaddr*)&client_addr,
83 &len);
84 close(sock);
85 if(ret < 0)
86 {
87 perror("Server: Error receiving");
88 return 1;
89
90 }
91 return 0;
92}
93
diff --git a/recipes-mac/smack/udp-smack-test_1.0.bb b/recipes-mac/smack/udp-smack-test_1.0.bb
new file mode 100644
index 0000000..9193f89
--- /dev/null
+++ b/recipes-mac/smack/udp-smack-test_1.0.bb
@@ -0,0 +1,23 @@
1SUMMARY = "Binary used to test smack udp sockets"
2DESCRIPTION = "Server and client binaries used to test smack attributes on UDP sockets"
3LICENSE = "MIT"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
5
6SRC_URI = "file://udp_server.c \
7 file://udp_client.c \
8 file://test_smack_udp_sockets.sh \
9"
10
11S = "${WORKDIR}"
12do_compile() {
13 ${CC} udp_client.c ${LDFLAGS} -o udp_client
14 ${CC} udp_server.c ${LDFLAGS} -o udp_server
15}
16
17do_install() {
18 install -d ${D}${bindir}
19 install -d ${D}${sbindir}
20 install -m 0755 udp_server ${D}${bindir}
21 install -m 0755 udp_client ${D}${bindir}
22 install -m 0755 test_smack_udp_sockets.sh ${D}${sbindir}
23}