github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/optical_drive.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 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 21 22 import ( 23 "fmt" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/apparmor" 27 "github.com/snapcore/snapd/snap" 28 ) 29 30 const opticalDriveSummary = `allows access to optical drives` 31 32 const opticalDriveBaseDeclarationSlots = ` 33 optical-drive: 34 allow-installation: 35 slot-snap-type: 36 - core 37 deny-connection: 38 plug-attributes: 39 write: true 40 deny-auto-connection: 41 plug-attributes: 42 write: true 43 ` 44 45 const opticalDriveConnectedPlugAppArmor = ` 46 # Allow read access to optical drives 47 /dev/sr[0-9]* r, 48 /dev/scd[0-9]* r, 49 # allow all generic scsi devices here and use the device cgroup to 50 # differentiate optical drives 51 /dev/sg[0-9]* r, 52 @{PROC}/sys/dev/cdrom/info r, 53 /run/udev/data/b11:[0-9]* r, 54 ` 55 56 var opticalDriveConnectedPlugUDev = []string{ 57 `KERNEL=="sr[0-9]*"`, 58 `KERNEL=="scd[0-9]*"`, 59 // ATTRS{type} below takes scsi peripheral device types. 60 // Type 4 is 'Write-once device'; type 5 is 'CD/DVD-ROM device' 61 // ref: https://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type 62 `SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5"`, 63 } 64 65 // opticalDriveInterface is the type for optical drive interfaces. 66 type opticalDriveInterface struct { 67 commonInterface 68 } 69 70 // BeforePrepareSlot checks and possibly modifies a slot. 71 // Valid "optical-drive" slots may contain the attribute "write". 72 // If defined, the attribute "write" must be either "true" or "false". 73 func (iface *opticalDriveInterface) BeforePreparePlug(plug *snap.PlugInfo) error { 74 // It's fine if 'write' isn't specified, but if it is, it needs to be bool 75 if w, ok := plug.Attrs["write"]; ok { 76 _, ok = w.(bool) 77 if !ok { 78 return fmt.Errorf(`optical-drive "write" attribute must be a boolean`) 79 } 80 } 81 82 return nil 83 } 84 85 func (iface *opticalDriveInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 86 var write bool 87 _ = plug.Attr("write", &write) 88 89 // Add the common readonly policy 90 spec.AddSnippet(opticalDriveConnectedPlugAppArmor) 91 92 // 'write: true' grants write access to the devices 93 if write { 94 spec.AddSnippet("# Allow write access to optical drives") 95 spec.AddSnippet("/dev/sr[0-9]* w,") 96 spec.AddSnippet("/dev/scd[0-9]* w,") 97 spec.AddSnippet("/dev/sg[0-9]* w,") 98 } 99 return nil 100 } 101 102 func init() { 103 registerIface(&opticalDriveInterface{commonInterface: commonInterface{ 104 name: "optical-drive", 105 summary: opticalDriveSummary, 106 implicitOnCore: false, 107 implicitOnClassic: true, 108 baseDeclarationSlots: opticalDriveBaseDeclarationSlots, 109 connectedPlugUDev: opticalDriveConnectedPlugUDev, 110 reservedForOS: true, 111 }}) 112 }