Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

o/hookstate/ctlcmd: add a new exit code for is-connected for cases when the peer is from the same snap #10024

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions overlord/hookstate/ctlcmd/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
const (
NotASnapCode = notASnapCode
ClassicSnapCode = classicSnapCode
PeerIsSelfCode = peerIsSelfCode
)

var AttributesTask = attributesTask
Expand Down
8 changes: 7 additions & 1 deletion overlord/hookstate/ctlcmd/is_connected.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var cgroupSnapNameFromPid = cgroup.SnapNameFromPid
const (
classicSnapCode = 10
notASnapCode = 11
peerIsSelfCode = 12
)

type isConnectedCommand struct {
Expand Down Expand Up @@ -64,7 +65,8 @@ The --pid and --aparmor-label options can be used to determine whether
a plug or slot is connected to the snap identified by the given
process ID or AppArmor label. In this mode, additional failure exit
codes may be returned: 10 if the other snap is not connected but uses
classic confinement, or 11 if the other process is not snap confined.
classic confinement, 11 if the other process is not snap confined, or
12 if the other process belongs to the same snap.

The --pid and --apparmor-label options may only be used with slots of
interface type "pulseaudio", "audio-record", or "cups-control".
Expand Down Expand Up @@ -173,6 +175,10 @@ func (c *isConnectedCommand) Execute(args []string) error {
}
}

if otherSnap != nil && otherSnap.InstanceName() == snapName {
return &UnsuccessfulError{ExitCode: peerIsSelfCode}
}

if otherSnap != nil && otherSnap.Confinement == snap.ClassicConfinement {
return &UnsuccessfulError{ExitCode: classicSnapCode}
}
Expand Down
8 changes: 8 additions & 0 deletions overlord/hookstate/ctlcmd/is_connected_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ var isConnectedTests = []struct {
// snap1:audio-record slot is not connected to classic snap5
args: []string{"is-connected", "--pid", "1005", "audio-record"},
exitCode: ctlcmd.ClassicSnapCode,
}, {
// snap1:audio-record slot is not connected to snap1 (self)
args: []string{"is-connected", "--pid", "1001", "audio-record"},
exitCode: ctlcmd.PeerIsSelfCode,
}, {
// snap1:plug1 does not use an allowed interface
args: []string{"is-connected", "--apparmor-label", "snap.snap2.app", "plug1"},
Expand Down Expand Up @@ -132,6 +136,10 @@ var isConnectedTests = []struct {
// snap1:audio-record slot is not connected to classic snap5
args: []string{"is-connected", "--apparmor-label", "snap.snap5.app", "audio-record"},
exitCode: ctlcmd.ClassicSnapCode,
}, {
// snap1:audio-record slot is not connected to snap1 (self)
args: []string{"is-connected", "--apparmor-label", "snap.snap1.app", "audio-record"},
exitCode: ctlcmd.PeerIsSelfCode,
}}

func mockInstalledSnap(c *C, st *state.State, snapYaml string) {
Expand Down
23 changes: 17 additions & 6 deletions tests/main/snapctl-is-connected-pid/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ restore: |
execute: |
echo "The test-snap1 service is running"
systemctl is-active snap.test-snap1.svc.service
svc_pid=$(systemctl show --property=MainPID snap.test-snap1.svc.service | cut -d = -f 2)
svc1_pid=$(systemctl show --property=MainPID snap.test-snap1.svc.service | cut -d = -f 2)

echo "The test-snap2 service is running"
systemctl is-active snap.test-snap2.svc.service
svc2_pid=$(systemctl show --property=MainPID snap.test-snap2.svc.service | cut -d = -f 2)

expect_status() {
expected="$1"
Expand All @@ -39,7 +43,7 @@ execute: |
not test-snap2.snapctl is-connected foo-slot

echo "Disconnected interfaces are not connected to a snap process"
expect_status 1 test-snap2.snapctl is-connected --pid "$svc_pid" foo-slot
expect_status 1 test-snap2.snapctl is-connected --pid "$svc1_pid" foo-slot

echo "Disconnected interfaces are not connected to non-snap process"
expect_status 11 test-snap2.snapctl is-connected --pid 1 foo-slot
Expand All @@ -48,18 +52,25 @@ execute: |
snap connect test-snap1:foo-plug test-snap2:foo-slot

echo "Connected interfaces report as connected to snap process"
test-snap2.snapctl is-connected --pid "$svc_pid" foo-slot
test-snap2.snapctl is-connected --pid "$svc1_pid" foo-slot

echo "Interfaces still not connected to non-snap process"
expect_status 11 test-snap2.snapctl is-connected --pid 1 foo-slot

echo "A special exit code is returned for connections from the same snap"
expect_status 12 test-snap2.snapctl is-connected --pid "$svc2_pid" foo-slot

if [[ "$(snap debug confinement)" = strict ]]; then
svc_label=$(sed 's/ (.*)$//' < "/proc/$svc_pid/attr/current")
svc1_label=$(sed 's/ (.*)$//' < "/proc/$svc1_pid/attr/current")
svc2_label=$(sed 's/ (.*)$//' < "/proc/$svc2_pid/attr/current")

echo "We can detect connected interfaces by AppArmor label too"
test-snap2.snapctl is-connected --apparmor-label "$svc_label" foo-slot
test-snap2.snapctl is-connected --apparmor-label "$svc1_label" foo-slot
snap disconnect test-snap1:foo-plug test-snap2:foo-slot
expect_status 1 test-snap2.snapctl is-connected --apparmor-label "$svc_label" foo-slot
expect_status 1 test-snap2.snapctl is-connected --apparmor-label "$svc1_label" foo-slot

echo "Without an interface connection, labels for the same snap return a special exit code"
expect_status 12 test-snap2.snapctl is-connected --apparmor-label "$svc2_label" foo-slot

echo "Non-snap AppArmor labels return a special exit code"
expect_status 11 test-snap2.snapctl is-connected --apparmor-label /usr/bin/evince foo-slot
Expand Down
4 changes: 4 additions & 0 deletions tests/main/snapctl-is-connected-pid/test-snap2/bin/service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

echo "service running"
exec sleep infinity
3 changes: 3 additions & 0 deletions tests/main/snapctl-is-connected-pid/test-snap2/meta/snap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ slots:
apps:
snapctl:
command: bin/run-snapctl.sh
svc:
command: bin/service.sh
daemon: simple