gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/posix_mq_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2022 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package builtin_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 "gitee.com/mysnapcore/mysnapd/interfaces" 26 "gitee.com/mysnapcore/mysnapd/interfaces/apparmor" 27 "gitee.com/mysnapcore/mysnapd/interfaces/builtin" 28 "gitee.com/mysnapcore/mysnapd/interfaces/seccomp" 29 apparmor_sandbox "gitee.com/mysnapcore/mysnapd/sandbox/apparmor" 30 "gitee.com/mysnapcore/mysnapd/snap" 31 "gitee.com/mysnapcore/mysnapd/snap/snaptest" 32 "gitee.com/mysnapcore/mysnapd/testutil" 33 ) 34 35 const slotSnapInfoYaml = `name: producer 36 version: 1.0 37 38 slots: 39 test-rw: 40 interface: posix-mq 41 path: /test-rw 42 permissions: 43 - read 44 - write 45 46 test-default: 47 interface: posix-mq 48 path: /test-default 49 50 test-ro: 51 interface: posix-mq 52 path: /test-ro 53 permissions: 54 - read 55 56 test-all-perms: 57 interface: posix-mq 58 path: /test-all-perms 59 permissions: 60 - create 61 - delete 62 - read 63 - write 64 65 test-path-array: 66 interface: posix-mq 67 path: 68 - /test-array-1 69 - /test-array-2 70 - /test-array-3 71 72 test-empty-path-array: 73 interface: posix-mq 74 path: [] 75 76 test-one-empty-path-array: 77 interface: posix-mq 78 path: 79 - /test-array-1 80 - "" 81 82 test-empty-path: 83 interface: posix-mq 84 path: "" 85 86 test-invalid-path-1: 87 interface: posix-mq 88 path: ../../test-invalid 89 90 test-invalid-path-2: 91 interface: posix-mq 92 path: /test-invalid-2"[ 93 94 test-invalid-path-3: 95 interface: posix-mq 96 path: 97 this-is-not-a-valid-path: true 98 99 test-invalid-path-4: 100 interface: posix-mq 101 102 test-invalid-path-5: 103 interface: posix-mq 104 path: /. 105 106 test-invalid-perms-1: 107 interface: posix-mq 108 path: /test-invalid-perms-1 109 permissions: 110 - create 111 - delete 112 - break-everything 113 114 test-invalid-perms-2: 115 interface: posix-mq 116 path: /test-invalid-perms-2 117 permissions: not-a-list 118 119 test-invalid-perms-3: 120 interface: posix-mq 121 path: /test-invalid-perms-3 122 permissions: 123 - create 124 - [not-a-string] 125 126 test-label: 127 interface: posix-mq 128 posix-mq: this-is-a-test-label 129 path: /test-label 130 131 test-broken-label: 132 interface: posix-mq 133 posix-mq: 134 - broken 135 path: /test-default 136 137 apps: 138 app: 139 command: foo 140 slots: 141 - test-default-rw 142 - test-rw 143 - test-ro 144 - test-all-perms 145 - test-invalid-path-1 146 - test-invalid-path-2 147 ` 148 149 const defaultRWPlugSnapInfoYaml = `name: consumer 150 version: 1.0 151 152 plugs: 153 test-default: 154 interface: posix-mq 155 156 apps: 157 app: 158 command: foo 159 plugs: [test-default] 160 ` 161 162 const rwPlugSnapInfoYaml = `name: consumer 163 version: 1.0 164 165 plugs: 166 test-rw: 167 interface: posix-mq 168 169 apps: 170 app: 171 command: foo 172 plugs: [test-rw] 173 ` 174 175 const roPlugSnapInfoYaml = `name: consumer 176 version: 1.0 177 178 plugs: 179 test-ro: 180 interface: posix-mq 181 182 apps: 183 app: 184 command: foo 185 plugs: [test-ro] 186 ` 187 188 const allPermsPlugSnapInfoYaml = `name: consumer 189 version: 1.0 190 191 plugs: 192 test-all-perms: 193 interface: posix-mq 194 195 apps: 196 app: 197 command: foo 198 plugs: [test-all-perms] 199 ` 200 201 const pathArrayPlugSnapInfoYaml = `name: consumer 202 version: 1.0 203 204 plugs: 205 test-path-array: 206 interface: posix-mq 207 208 apps: 209 app: 210 command: foo 211 plugs: [test-path-array] 212 ` 213 214 const invalidPerms1PlugSnapInfoYaml = `name: consumer 215 version: 1.0 216 217 plugs: 218 test-invalid-perms-1: 219 interface: posix-mq 220 221 apps: 222 app: 223 command: foo 224 plugs: [test-invalid-perms-1] 225 ` 226 227 const testLabelPlugSnapInfoYaml = `name: consumer 228 version: 1.0 229 230 plugs: 231 test-label: 232 interface: posix-mq 233 posix-mq: this-is-a-test-label 234 235 apps: 236 app: 237 command: foo 238 plugs: [test-label] 239 ` 240 241 const invalidPerms3PlugSnapInfoYaml = `name: consumer 242 version: 1.0 243 244 plugs: 245 test-invalid-perms-3: 246 interface: posix-mq 247 248 apps: 249 app: 250 command: foo 251 plugs: [test-invalid-perms-3] 252 ` 253 254 const testInvalidLabelPlugSnapInfoYaml = `name: consumer 255 version: 1.0 256 257 plugs: 258 test-invalid-label: 259 interface: posix-mq 260 posix-mq: 261 - this-is-a-broken-test-label 262 263 apps: 264 app: 265 command: foo 266 plugs: [test-invalid-label] 267 ` 268 269 type PosixMQInterfaceSuite struct { 270 testutil.BaseTest 271 272 iface interfaces.Interface 273 274 testReadWriteSlotInfo *snap.SlotInfo 275 testReadWriteSlot *interfaces.ConnectedSlot 276 testReadWritePlugInfo *snap.PlugInfo 277 testReadWritePlug *interfaces.ConnectedPlug 278 279 testDefaultPermsSlotInfo *snap.SlotInfo 280 testDefaultPermsSlot *interfaces.ConnectedSlot 281 testDefaultPermsPlugInfo *snap.PlugInfo 282 testDefaultPermsPlug *interfaces.ConnectedPlug 283 284 testReadOnlySlotInfo *snap.SlotInfo 285 testReadOnlySlot *interfaces.ConnectedSlot 286 testReadOnlyPlugInfo *snap.PlugInfo 287 testReadOnlyPlug *interfaces.ConnectedPlug 288 289 testAllPermsSlotInfo *snap.SlotInfo 290 testAllPermsSlot *interfaces.ConnectedSlot 291 testAllPermsPlugInfo *snap.PlugInfo 292 testAllPermsPlug *interfaces.ConnectedPlug 293 294 testPathArraySlotInfo *snap.SlotInfo 295 testPathArraySlot *interfaces.ConnectedSlot 296 testPathArrayPlugInfo *snap.PlugInfo 297 testPathArrayPlug *interfaces.ConnectedPlug 298 299 testEmptyPathArraySlotInfo *snap.SlotInfo 300 testEmptyPathArraySlot *interfaces.ConnectedSlot 301 302 testOneEmptyPathArraySlotInfo *snap.SlotInfo 303 testOneEmptyPathArraySlot *interfaces.ConnectedSlot 304 305 testEmptyPathSlotInfo *snap.SlotInfo 306 testEmptyPathSlot *interfaces.ConnectedSlot 307 308 testInvalidPath1SlotInfo *snap.SlotInfo 309 testInvalidPath1Slot *interfaces.ConnectedSlot 310 311 testInvalidPath2SlotInfo *snap.SlotInfo 312 testInvalidPath2Slot *interfaces.ConnectedSlot 313 314 testInvalidPath3SlotInfo *snap.SlotInfo 315 testInvalidPath3Slot *interfaces.ConnectedSlot 316 317 testInvalidPath4SlotInfo *snap.SlotInfo 318 testInvalidPath4Slot *interfaces.ConnectedSlot 319 320 testInvalidPath5SlotInfo *snap.SlotInfo 321 testInvalidPath5Slot *interfaces.ConnectedSlot 322 323 testInvalidPerms1SlotInfo *snap.SlotInfo 324 testInvalidPerms1Slot *interfaces.ConnectedSlot 325 testInvalidPerms1PlugInfo *snap.PlugInfo 326 testInvalidPerms1Plug *interfaces.ConnectedPlug 327 328 testInvalidPerms2SlotInfo *snap.SlotInfo 329 testInvalidPerms2Slot *interfaces.ConnectedSlot 330 331 testInvalidPerms3SlotInfo *snap.SlotInfo 332 testInvalidPerms3Slot *interfaces.ConnectedSlot 333 testInvalidPerms3PlugInfo *snap.PlugInfo 334 testInvalidPerms3Plug *interfaces.ConnectedPlug 335 336 testLabelSlotInfo *snap.SlotInfo 337 testLabelSlot *interfaces.ConnectedSlot 338 testLabelPlugInfo *snap.PlugInfo 339 testLabelPlug *interfaces.ConnectedPlug 340 341 testInvalidLabelSlotInfo *snap.SlotInfo 342 testInvalidLabelSlot *interfaces.ConnectedSlot 343 testInvalidLabelPlugInfo *snap.PlugInfo 344 testInvalidLabelPlug *interfaces.ConnectedPlug 345 } 346 347 var _ = Suite(&PosixMQInterfaceSuite{ 348 iface: builtin.MustInterface("posix-mq"), 349 }) 350 351 func (s *PosixMQInterfaceSuite) SetUpTest(c *C) { 352 s.BaseTest.SetUpTest(c) 353 354 slotSnap := snaptest.MockInfo(c, slotSnapInfoYaml, nil) 355 356 s.testReadWriteSlotInfo = slotSnap.Slots["test-rw"] 357 s.testReadWriteSlot = interfaces.NewConnectedSlot(s.testReadWriteSlotInfo, nil, nil) 358 359 s.testDefaultPermsSlotInfo = slotSnap.Slots["test-default"] 360 s.testDefaultPermsSlot = interfaces.NewConnectedSlot(s.testDefaultPermsSlotInfo, nil, nil) 361 362 s.testReadOnlySlotInfo = slotSnap.Slots["test-ro"] 363 s.testReadOnlySlot = interfaces.NewConnectedSlot(s.testReadOnlySlotInfo, nil, nil) 364 365 s.testAllPermsSlotInfo = slotSnap.Slots["test-all-perms"] 366 s.testAllPermsSlot = interfaces.NewConnectedSlot(s.testAllPermsSlotInfo, nil, nil) 367 368 s.testPathArraySlotInfo = slotSnap.Slots["test-path-array"] 369 s.testPathArraySlot = interfaces.NewConnectedSlot(s.testPathArraySlotInfo, nil, nil) 370 371 s.testEmptyPathArraySlotInfo = slotSnap.Slots["test-empty-path-array"] 372 s.testEmptyPathArraySlot = interfaces.NewConnectedSlot(s.testEmptyPathArraySlotInfo, nil, nil) 373 374 s.testOneEmptyPathArraySlotInfo = slotSnap.Slots["test-one-empty-path-array"] 375 s.testOneEmptyPathArraySlot = interfaces.NewConnectedSlot(s.testOneEmptyPathArraySlotInfo, nil, nil) 376 377 s.testEmptyPathSlotInfo = slotSnap.Slots["test-empty-path"] 378 s.testEmptyPathSlot = interfaces.NewConnectedSlot(s.testEmptyPathSlotInfo, nil, nil) 379 380 s.testInvalidPath1SlotInfo = slotSnap.Slots["test-invalid-path-1"] 381 s.testInvalidPath1Slot = interfaces.NewConnectedSlot(s.testInvalidPath1SlotInfo, nil, nil) 382 383 s.testInvalidPath2SlotInfo = slotSnap.Slots["test-invalid-path-2"] 384 s.testInvalidPath2Slot = interfaces.NewConnectedSlot(s.testInvalidPath2SlotInfo, nil, nil) 385 386 s.testInvalidPath3SlotInfo = slotSnap.Slots["test-invalid-path-3"] 387 s.testInvalidPath3Slot = interfaces.NewConnectedSlot(s.testInvalidPath3SlotInfo, nil, nil) 388 389 s.testInvalidPath4SlotInfo = slotSnap.Slots["test-invalid-path-4"] 390 s.testInvalidPath4Slot = interfaces.NewConnectedSlot(s.testInvalidPath4SlotInfo, nil, nil) 391 392 s.testInvalidPath5SlotInfo = slotSnap.Slots["test-invalid-path-5"] 393 s.testInvalidPath5Slot = interfaces.NewConnectedSlot(s.testInvalidPath5SlotInfo, nil, nil) 394 395 s.testInvalidPerms1SlotInfo = slotSnap.Slots["test-invalid-perms-1"] 396 s.testInvalidPerms1Slot = interfaces.NewConnectedSlot(s.testInvalidPerms1SlotInfo, nil, nil) 397 398 s.testInvalidPerms2SlotInfo = slotSnap.Slots["test-invalid-perms-2"] 399 s.testInvalidPerms2Slot = interfaces.NewConnectedSlot(s.testInvalidPerms2SlotInfo, nil, nil) 400 401 s.testInvalidPerms3SlotInfo = slotSnap.Slots["test-invalid-perms-3"] 402 s.testInvalidPerms3Slot = interfaces.NewConnectedSlot(s.testInvalidPerms3SlotInfo, nil, nil) 403 404 s.testLabelSlotInfo = slotSnap.Slots["test-label"] 405 s.testLabelSlot = interfaces.NewConnectedSlot(s.testLabelSlotInfo, nil, nil) 406 407 s.testInvalidLabelSlotInfo = slotSnap.Slots["test-broken-label"] 408 s.testInvalidLabelSlot = interfaces.NewConnectedSlot(s.testInvalidLabelSlotInfo, nil, nil) 409 410 plugSnap0 := snaptest.MockInfo(c, rwPlugSnapInfoYaml, nil) 411 s.testReadWritePlugInfo = plugSnap0.Plugs["test-rw"] 412 s.testReadWritePlug = interfaces.NewConnectedPlug(s.testReadWritePlugInfo, nil, nil) 413 414 plugSnap1 := snaptest.MockInfo(c, defaultRWPlugSnapInfoYaml, nil) 415 s.testDefaultPermsPlugInfo = plugSnap1.Plugs["test-default"] 416 s.testDefaultPermsPlug = interfaces.NewConnectedPlug(s.testDefaultPermsPlugInfo, nil, nil) 417 418 plugSnap2 := snaptest.MockInfo(c, roPlugSnapInfoYaml, nil) 419 s.testReadOnlyPlugInfo = plugSnap2.Plugs["test-ro"] 420 s.testReadOnlyPlug = interfaces.NewConnectedPlug(s.testReadOnlyPlugInfo, nil, nil) 421 422 plugSnap3 := snaptest.MockInfo(c, allPermsPlugSnapInfoYaml, nil) 423 s.testAllPermsPlugInfo = plugSnap3.Plugs["test-all-perms"] 424 s.testAllPermsPlug = interfaces.NewConnectedPlug(s.testAllPermsPlugInfo, nil, nil) 425 426 plugSnap4 := snaptest.MockInfo(c, invalidPerms1PlugSnapInfoYaml, nil) 427 s.testInvalidPerms1PlugInfo = plugSnap4.Plugs["test-invalid-perms-1"] 428 s.testInvalidPerms1Plug = interfaces.NewConnectedPlug(s.testInvalidPerms1PlugInfo, nil, nil) 429 430 plugSnap5 := snaptest.MockInfo(c, testLabelPlugSnapInfoYaml, nil) 431 s.testLabelPlugInfo = plugSnap5.Plugs["test-label"] 432 s.testLabelPlug = interfaces.NewConnectedPlug(s.testLabelPlugInfo, nil, nil) 433 434 plugSnap6 := snaptest.MockInfo(c, testInvalidLabelPlugSnapInfoYaml, nil) 435 s.testInvalidLabelPlugInfo = plugSnap6.Plugs["test-invalid-label"] 436 s.testInvalidLabelPlug = interfaces.NewConnectedPlug(s.testInvalidLabelPlugInfo, nil, nil) 437 438 plugSnap7 := snaptest.MockInfo(c, invalidPerms3PlugSnapInfoYaml, nil) 439 s.testInvalidPerms3PlugInfo = plugSnap7.Plugs["test-invalid-perms-3"] 440 s.testInvalidPerms3Plug = interfaces.NewConnectedPlug(s.testInvalidPerms3PlugInfo, nil, nil) 441 442 plugSnap8 := snaptest.MockInfo(c, pathArrayPlugSnapInfoYaml, nil) 443 s.testPathArrayPlugInfo = plugSnap8.Plugs["test-path-array"] 444 s.testPathArrayPlug = interfaces.NewConnectedPlug(s.testPathArrayPlugInfo, nil, nil) 445 } 446 447 func (s *PosixMQInterfaceSuite) checkSlotSeccompSnippet(c *C, spec *seccomp.Specification) { 448 slotSnippet := spec.SnippetForTag("snap.producer.app") 449 c.Check(slotSnippet, testutil.Contains, "mq_open") 450 c.Check(slotSnippet, testutil.Contains, "mq_unlink") 451 c.Check(slotSnippet, testutil.Contains, "mq_getsetattr") 452 c.Check(slotSnippet, testutil.Contains, "mq_notify") 453 c.Check(slotSnippet, testutil.Contains, "mq_timedreceive") 454 c.Check(slotSnippet, testutil.Contains, "mq_timedsend") 455 } 456 457 func (s *PosixMQInterfaceSuite) TestReadWriteMQAppArmor(c *C) { 458 spec := &apparmor.Specification{} 459 err := spec.AddPermanentSlot(s.iface, s.testReadWriteSlotInfo) 460 c.Assert(err, IsNil) 461 err = spec.AddConnectedPlug(s.iface, s.testReadWritePlug, s.testReadWriteSlot) 462 c.Assert(err, IsNil) 463 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 464 465 slotSnippet := spec.SnippetForTag("snap.producer.app") 466 c.Check(slotSnippet, testutil.Contains, `# POSIX Message Queue slot: test-rw`) 467 c.Check(slotSnippet, testutil.Contains, `mqueue (open read write create delete) "/test-rw",`) 468 469 plugSnippet := spec.SnippetForTag("snap.consumer.app") 470 c.Check(plugSnippet, testutil.Contains, `# POSIX Message Queue plug: test-rw`) 471 c.Check(plugSnippet, testutil.Contains, `mqueue (read write open) "/test-rw",`) 472 } 473 474 func (s *PosixMQInterfaceSuite) TestReadWriteMQSeccomp(c *C) { 475 spec := &seccomp.Specification{} 476 err := spec.AddPermanentSlot(s.iface, s.testReadWriteSlotInfo) 477 c.Assert(err, IsNil) 478 err = spec.AddConnectedPlug(s.iface, s.testReadWritePlug, s.testReadWriteSlot) 479 c.Assert(err, IsNil) 480 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 481 482 s.checkSlotSeccompSnippet(c, spec) 483 plugSnippet := spec.SnippetForTag("snap.consumer.app") 484 c.Check(plugSnippet, testutil.Contains, "mq_open") 485 c.Check(plugSnippet, testutil.Contains, "mq_notify") 486 c.Check(plugSnippet, testutil.Contains, "mq_timedreceive") 487 c.Check(plugSnippet, testutil.Contains, "mq_timedsend") 488 c.Check(plugSnippet, testutil.Contains, "mq_getsetattr") 489 c.Check(plugSnippet, Not(testutil.Contains), "mq_unlink") 490 } 491 492 func (s *PosixMQInterfaceSuite) TestDefaultReadWriteMQAppArmor(c *C) { 493 spec := &apparmor.Specification{} 494 err := spec.AddPermanentSlot(s.iface, s.testDefaultPermsSlotInfo) 495 c.Assert(err, IsNil) 496 err = spec.AddConnectedPlug(s.iface, s.testDefaultPermsPlug, s.testDefaultPermsSlot) 497 c.Assert(err, IsNil) 498 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 499 500 slotSnippet := spec.SnippetForTag("snap.producer.app") 501 c.Check(slotSnippet, testutil.Contains, `# POSIX Message Queue slot: test-default`) 502 c.Check(slotSnippet, testutil.Contains, `mqueue (open read write create delete) "/test-default",`) 503 504 plugSnippet := spec.SnippetForTag("snap.consumer.app") 505 c.Check(plugSnippet, testutil.Contains, `# POSIX Message Queue plug: test-default`) 506 c.Check(plugSnippet, testutil.Contains, `mqueue (read write open) "/test-default",`) 507 } 508 509 func (s *PosixMQInterfaceSuite) TestDefaultReadWriteMQSeccomp(c *C) { 510 spec := &seccomp.Specification{} 511 err := spec.AddPermanentSlot(s.iface, s.testDefaultPermsSlotInfo) 512 c.Assert(err, IsNil) 513 err = spec.AddConnectedPlug(s.iface, s.testDefaultPermsPlug, s.testDefaultPermsSlot) 514 c.Assert(err, IsNil) 515 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 516 517 s.checkSlotSeccompSnippet(c, spec) 518 519 plugSnippet := spec.SnippetForTag("snap.consumer.app") 520 c.Check(plugSnippet, testutil.Contains, "mq_open") 521 c.Check(plugSnippet, testutil.Contains, "mq_notify") 522 c.Check(plugSnippet, testutil.Contains, "mq_timedreceive") 523 c.Check(plugSnippet, testutil.Contains, "mq_timedsend") 524 c.Check(plugSnippet, testutil.Contains, "mq_getsetattr") 525 c.Check(plugSnippet, Not(testutil.Contains), "mq_unlink") 526 } 527 528 func (s *PosixMQInterfaceSuite) TestReadOnlyMQAppArmor(c *C) { 529 spec := &apparmor.Specification{} 530 err := spec.AddPermanentSlot(s.iface, s.testReadOnlySlotInfo) 531 c.Assert(err, IsNil) 532 err = spec.AddConnectedPlug(s.iface, s.testReadOnlyPlug, s.testReadOnlySlot) 533 c.Assert(err, IsNil) 534 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 535 536 slotSnippet := spec.SnippetForTag("snap.producer.app") 537 c.Check(slotSnippet, testutil.Contains, `mqueue (open read write create delete) "/test-ro",`) 538 539 plugSnippet := spec.SnippetForTag("snap.consumer.app") 540 c.Check(plugSnippet, testutil.Contains, `mqueue (read open) "/test-ro",`) 541 } 542 543 func (s *PosixMQInterfaceSuite) TestReadOnlyMQSeccomp(c *C) { 544 spec := &seccomp.Specification{} 545 err := spec.AddPermanentSlot(s.iface, s.testReadOnlySlotInfo) 546 c.Assert(err, IsNil) 547 err = spec.AddConnectedPlug(s.iface, s.testReadOnlyPlug, s.testReadOnlySlot) 548 c.Assert(err, IsNil) 549 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 550 551 s.checkSlotSeccompSnippet(c, spec) 552 553 plugSnippet := spec.SnippetForTag("snap.consumer.app") 554 c.Check(plugSnippet, testutil.Contains, "mq_open") 555 c.Check(plugSnippet, testutil.Contains, "mq_notify") 556 c.Check(plugSnippet, testutil.Contains, "mq_timedreceive") 557 c.Check(plugSnippet, testutil.Contains, "mq_getsetattr") 558 c.Check(plugSnippet, Not(testutil.Contains), "mq_timedsend") 559 c.Check(plugSnippet, Not(testutil.Contains), "mq_unlink") 560 } 561 562 func (s *PosixMQInterfaceSuite) TestPathArrayMQAppArmor(c *C) { 563 spec := &apparmor.Specification{} 564 err := spec.AddPermanentSlot(s.iface, s.testPathArraySlotInfo) 565 c.Assert(err, IsNil) 566 err = spec.AddConnectedPlug(s.iface, s.testPathArrayPlug, s.testPathArraySlot) 567 c.Assert(err, IsNil) 568 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 569 570 slotSnippet := spec.SnippetForTag("snap.producer.app") 571 c.Check(slotSnippet, testutil.Contains, ` mqueue (open read write create delete) "/test-array-1", 572 mqueue (open read write create delete) "/test-array-2", 573 mqueue (open read write create delete) "/test-array-3", 574 `) 575 576 plugSnippet := spec.SnippetForTag("snap.consumer.app") 577 c.Check(plugSnippet, testutil.Contains, ` mqueue (read write open) "/test-array-1", 578 mqueue (read write open) "/test-array-2", 579 mqueue (read write open) "/test-array-3", 580 `) 581 } 582 583 func (s *PosixMQInterfaceSuite) TestPathArrayMQSeccomp(c *C) { 584 spec := &seccomp.Specification{} 585 err := spec.AddPermanentSlot(s.iface, s.testPathArraySlotInfo) 586 c.Assert(err, IsNil) 587 err = spec.AddConnectedPlug(s.iface, s.testPathArrayPlug, s.testPathArraySlot) 588 c.Assert(err, IsNil) 589 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 590 591 s.checkSlotSeccompSnippet(c, spec) 592 593 plugSnippet := spec.SnippetForTag("snap.consumer.app") 594 c.Check(plugSnippet, testutil.Contains, "mq_open") 595 c.Check(plugSnippet, testutil.Contains, "mq_notify") 596 c.Check(plugSnippet, testutil.Contains, "mq_timedreceive") 597 c.Check(plugSnippet, testutil.Contains, "mq_timedsend") 598 c.Check(plugSnippet, testutil.Contains, "mq_getsetattr") 599 c.Check(plugSnippet, Not(testutil.Contains), "mq_unlink") 600 } 601 602 func (s *PosixMQInterfaceSuite) TestAllPermsMQAppArmor(c *C) { 603 spec := &apparmor.Specification{} 604 err := spec.AddPermanentSlot(s.iface, s.testAllPermsSlotInfo) 605 c.Assert(err, IsNil) 606 err = spec.AddConnectedPlug(s.iface, s.testAllPermsPlug, s.testAllPermsSlot) 607 c.Assert(err, IsNil) 608 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 609 610 slotSnippet := spec.SnippetForTag("snap.producer.app") 611 c.Check(slotSnippet, testutil.Contains, `mqueue (open read write create delete) "/test-all-perms",`) 612 613 plugSnippet := spec.SnippetForTag("snap.consumer.app") 614 c.Check(plugSnippet, testutil.Contains, `mqueue (create delete read write open) "/test-all-perms",`) 615 } 616 617 func (s *PosixMQInterfaceSuite) TestAllPermsMQSeccomp(c *C) { 618 spec := &seccomp.Specification{} 619 err := spec.AddPermanentSlot(s.iface, s.testAllPermsSlotInfo) 620 c.Assert(err, IsNil) 621 err = spec.AddConnectedPlug(s.iface, s.testAllPermsPlug, s.testAllPermsSlot) 622 c.Assert(err, IsNil) 623 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app", "snap.producer.app"}) 624 625 s.checkSlotSeccompSnippet(c, spec) 626 627 plugSnippet := spec.SnippetForTag("snap.consumer.app") 628 c.Check(plugSnippet, testutil.Contains, "mq_open") 629 c.Check(plugSnippet, testutil.Contains, "mq_unlink") 630 c.Check(plugSnippet, testutil.Contains, "mq_getsetattr") 631 c.Check(plugSnippet, testutil.Contains, "mq_notify") 632 c.Check(plugSnippet, testutil.Contains, "mq_timedreceive") 633 c.Check(plugSnippet, testutil.Contains, "mq_timedsend") 634 } 635 636 func (s *PosixMQInterfaceSuite) TestPathValidationPosixMQ(c *C) { 637 spec := &apparmor.Specification{} 638 err := spec.AddPermanentSlot(s.iface, s.testInvalidPath1SlotInfo) 639 c.Check(err, ErrorMatches, 640 `posix-mq "path" attribute must conform to the POSIX message queue name specifications \(see "man mq_overview"\): /../../test-invalid`) 641 } 642 643 func (s *PosixMQInterfaceSuite) TestPathValidationAppArmorRegex(c *C) { 644 spec := &apparmor.Specification{} 645 err := spec.AddPermanentSlot(s.iface, s.testInvalidPath2SlotInfo) 646 c.Check(err, ErrorMatches, `posix-mq "path" attribute is invalid: /test-invalid-2"\["`) 647 } 648 649 func (s *PosixMQInterfaceSuite) TestPathStringValidation(c *C) { 650 spec := &apparmor.Specification{} 651 err := spec.AddPermanentSlot(s.iface, s.testInvalidPath3SlotInfo) 652 c.Check(err, ErrorMatches, `snap "producer" has interface "posix-mq" with invalid value type map\[string\]interface {} for "path" attribute: \*\[\]string`) 653 } 654 655 func (s *PosixMQInterfaceSuite) TestInvalidPerms1(c *C) { 656 spec := &apparmor.Specification{} 657 // The slot should function correctly here as it receives the full list 658 // of built-in permissions, not what's listed in the configuration 659 err := spec.AddPermanentSlot(s.iface, s.testInvalidPerms1SlotInfo) 660 c.Assert(err, IsNil) 661 // The plug should fail to connect as it receives the given list of 662 // invalid permissions 663 err = spec.AddConnectedPlug(s.iface, s.testInvalidPerms1Plug, s.testInvalidPerms1Slot) 664 c.Check(err, ErrorMatches, 665 `posix-mq slot permission "break-everything" not valid, must be one of \[open read write create delete\]`) 666 } 667 668 func (s *PosixMQInterfaceSuite) TestInvalidPerms3(c *C) { 669 spec := &apparmor.Specification{} 670 err := spec.AddPermanentSlot(s.iface, s.testInvalidPerms3SlotInfo) 671 c.Assert(err, IsNil) 672 err = spec.AddConnectedPlug(s.iface, s.testInvalidPerms3Plug, s.testInvalidPerms3Slot) 673 c.Check(err, ErrorMatches, 674 `snap "producer" has interface "posix-mq" with invalid value type \[\]interface {} for "permissions" attribute: \*\[\]string`) 675 } 676 677 func (s *PosixMQInterfaceSuite) TestName(c *C) { 678 c.Assert(s.iface.Name(), Equals, "posix-mq") 679 } 680 681 func (s *PosixMQInterfaceSuite) TestNoAppArmor(c *C) { 682 // Ensure that the interface does not fail if AppArmor is unsupported 683 restore := apparmor_sandbox.MockLevel(apparmor_sandbox.Unsupported) 684 defer restore() 685 686 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testReadWriteSlotInfo), IsNil) 687 c.Check(interfaces.BeforePreparePlug(s.iface, s.testReadWritePlugInfo), IsNil) 688 } 689 690 func (s *PosixMQInterfaceSuite) TestFeatureDetection(c *C) { 691 // Ensure that the interface fails if the mqueue feature is not present 692 restore := apparmor_sandbox.MockFeatures([]string{}, nil, []string{}, nil) 693 defer restore() 694 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testReadWriteSlotInfo), ErrorMatches, 695 `AppArmor does not support POSIX message queues - cannot setup or connect interfaces`) 696 } 697 698 func (s *PosixMQInterfaceSuite) checkSlotPosixMQAttr(c *C, slot *snap.SlotInfo) { 699 c.Check(slot.Attrs["posix-mq"], Equals, slot.Name) 700 } 701 702 func (s *PosixMQInterfaceSuite) checkPlugPosixMQAttr(c *C, plug *snap.PlugInfo) { 703 c.Check(plug.Attrs["posix-mq"], Equals, plug.Name) 704 } 705 706 func (s *PosixMQInterfaceSuite) TestSanitizeSlot(c *C) { 707 // Ensure that the mqueue feature is detected 708 restore := apparmor_sandbox.MockFeatures([]string{}, nil, []string{"mqueue"}, nil) 709 defer restore() 710 711 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testReadWriteSlotInfo), IsNil) 712 s.checkSlotPosixMQAttr(c, s.testReadWriteSlotInfo) 713 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testDefaultPermsSlotInfo), IsNil) 714 s.checkSlotPosixMQAttr(c, s.testDefaultPermsSlotInfo) 715 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testReadOnlySlotInfo), IsNil) 716 s.checkSlotPosixMQAttr(c, s.testReadOnlySlotInfo) 717 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testAllPermsSlotInfo), IsNil) 718 s.checkSlotPosixMQAttr(c, s.testAllPermsSlotInfo) 719 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testPathArraySlotInfo), IsNil) 720 s.checkSlotPosixMQAttr(c, s.testPathArraySlotInfo) 721 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.testLabelSlotInfo), IsNil) 722 c.Check(s.testLabelSlotInfo.Attrs["posix-mq"], Equals, "this-is-a-test-label") 723 724 // These should return errors due to invalid configuration 725 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPath1SlotInfo), ErrorMatches, 726 `posix-mq "path" attribute must conform to the POSIX message queue name specifications \(see "man mq_overview"\): /../../test-invalid`) 727 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPath2SlotInfo), ErrorMatches, 728 `posix-mq "path" attribute is invalid: /test-invalid-2"\["`) 729 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPath3SlotInfo), ErrorMatches, 730 `snap "producer" has interface "posix-mq" with invalid value type map\[string\]interface {} for "path" attribute: \*\[\]string`) 731 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPath4SlotInfo), ErrorMatches, 732 `posix-mq slot requires the "path" attribute`) 733 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPath5SlotInfo), ErrorMatches, 734 `posix-mq "path" attribute is not a clean path: "/."`) 735 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPerms1SlotInfo), ErrorMatches, 736 `posix-mq slot permission "break-everything" not valid, must be one of \[open read write create delete\]`) 737 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidPerms2SlotInfo), ErrorMatches, 738 `snap "producer" has interface "posix-mq" with invalid value type string for "permissions" attribute: \*\[\]string`) 739 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testInvalidLabelSlotInfo), ErrorMatches, 740 `posix-mq "posix-mq" attribute must be a string, not \[broken\]`) 741 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testEmptyPathArraySlotInfo), ErrorMatches, 742 `posix-mq slot requires at least one value in the "path" attribute`) 743 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testEmptyPathSlotInfo), ErrorMatches, 744 `posix-mq slot "path" attribute values cannot be empty`) 745 c.Check(interfaces.BeforePrepareSlot(s.iface, s.testOneEmptyPathArraySlotInfo), ErrorMatches, 746 `posix-mq slot "path" attribute values cannot be empty`) 747 } 748 749 func (s *PosixMQInterfaceSuite) TestSanitizePlug(c *C) { 750 // Ensure that the mqueue feature is detected 751 restore := apparmor_sandbox.MockFeatures([]string{}, nil, []string{"mqueue"}, nil) 752 defer restore() 753 754 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testReadWritePlugInfo), IsNil) 755 s.checkPlugPosixMQAttr(c, s.testReadWritePlugInfo) 756 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testDefaultPermsPlugInfo), IsNil) 757 s.checkPlugPosixMQAttr(c, s.testDefaultPermsPlugInfo) 758 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testReadOnlyPlugInfo), IsNil) 759 s.checkPlugPosixMQAttr(c, s.testReadOnlyPlugInfo) 760 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testAllPermsPlugInfo), IsNil) 761 s.checkPlugPosixMQAttr(c, s.testAllPermsPlugInfo) 762 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testPathArrayPlugInfo), IsNil) 763 s.checkPlugPosixMQAttr(c, s.testPathArrayPlugInfo) 764 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testInvalidPerms1PlugInfo), IsNil) 765 s.checkPlugPosixMQAttr(c, s.testInvalidPerms1PlugInfo) 766 c.Assert(interfaces.BeforePreparePlug(s.iface, s.testLabelPlugInfo), IsNil) 767 c.Check(s.testLabelPlugInfo.Attrs["posix-mq"], Equals, "this-is-a-test-label") 768 769 c.Check(interfaces.BeforePreparePlug(s.iface, s.testInvalidLabelPlugInfo), ErrorMatches, 770 `posix-mq "posix-mq" attribute must be a string, not \[this-is-a-broken-test-label\]`) 771 } 772 773 func (s *PosixMQInterfaceSuite) TestInterfaces(c *C) { 774 c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) 775 } 776 777 func (s *PosixMQInterfaceSuite) TestAutoConnect(c *C) { 778 c.Assert(s.iface.AutoConnect(s.testReadWritePlugInfo, s.testReadWriteSlotInfo), Equals, true) 779 } 780 781 func (s *PosixMQInterfaceSuite) TestStaticInfo(c *C) { 782 si := interfaces.StaticInfoOf(s.iface) 783 c.Check(si.ImplicitOnCore, Equals, false) 784 c.Check(si.ImplicitOnClassic, Equals, false) 785 c.Check(si.Summary, Equals, `allows access to POSIX message queues`) 786 }