Kernel modules add-on flag need no extra cap (#2569)

This commit is contained in:
Pascal Vizeli 2021-02-15 20:42:03 +01:00 committed by GitHub
parent 72e5d800d5
commit b61a747876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 50 deletions

View File

@ -71,6 +71,7 @@ from ..const import (
AddonStartup, AddonStartup,
) )
from ..coresys import CoreSys, CoreSysAttributes from ..coresys import CoreSys, CoreSysAttributes
from ..docker.const import Capabilities
from .options import AddonOptions, UiOptions from .options import AddonOptions, UiOptions
from .validate import RE_SERVICE, RE_VOLUME from .validate import RE_SERVICE, RE_VOLUME
@ -307,7 +308,7 @@ class AddonModel(CoreSysAttributes, ABC):
return self.data.get(ATTR_ENVIRONMENT) return self.data.get(ATTR_ENVIRONMENT)
@property @property
def privileged(self) -> List[str]: def privileged(self) -> List[Capabilities]:
"""Return list of privilege.""" """Return list of privilege."""
return self.data.get(ATTR_PRIVILEGED, []) return self.data.get(ATTR_PRIVILEGED, [])

View File

@ -6,18 +6,8 @@ import logging
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from ..const import ( from ..const import ROLE_ADMIN, ROLE_MANAGER, SECURITY_DISABLE, SECURITY_PROFILE
PRIVILEGED_DAC_READ_SEARCH, from ..docker.const import Capabilities
PRIVILEGED_NET_ADMIN,
PRIVILEGED_SYS_ADMIN,
PRIVILEGED_SYS_MODULE,
PRIVILEGED_SYS_PTRACE,
PRIVILEGED_SYS_RAWIO,
ROLE_ADMIN,
ROLE_MANAGER,
SECURITY_DISABLE,
SECURITY_PROFILE,
)
if TYPE_CHECKING: if TYPE_CHECKING:
from .model import AddonModel from .model import AddonModel
@ -46,16 +36,19 @@ def rating_security(addon: AddonModel) -> int:
rating += 1 rating += 1
# Privileged options # Privileged options
if any( if (
any(
privilege in addon.privileged privilege in addon.privileged
for privilege in ( for privilege in (
PRIVILEGED_NET_ADMIN, Capabilities.NET_ADMIN,
PRIVILEGED_SYS_ADMIN, Capabilities.SYS_ADMIN,
PRIVILEGED_SYS_RAWIO, Capabilities.SYS_RAWIO,
PRIVILEGED_SYS_PTRACE, Capabilities.SYS_PTRACE,
PRIVILEGED_SYS_MODULE, Capabilities.SYS_MODULE,
PRIVILEGED_DAC_READ_SEARCH, Capabilities.DAC_READ_SEARCH,
) )
)
or addon.with_kernel_modules
): ):
rating += -1 rating += -1

View File

@ -82,7 +82,6 @@ from ..const import (
ATTR_VIDEO, ATTR_VIDEO,
ATTR_WATCHDOG, ATTR_WATCHDOG,
ATTR_WEBUI, ATTR_WEBUI,
PRIVILEGED_ALL,
ROLE_ALL, ROLE_ALL,
ROLE_DEFAULT, ROLE_DEFAULT,
AddonBoot, AddonBoot,
@ -91,6 +90,7 @@ from ..const import (
AddonState, AddonState,
) )
from ..discovery.validate import valid_discovery_service from ..discovery.validate import valid_discovery_service
from ..docker.const import Capabilities
from ..validate import ( from ..validate import (
docker_image, docker_image,
docker_ports, docker_ports,
@ -233,7 +233,7 @@ _SCHEMA_ADDON_CONFIG = vol.Schema(
vol.Optional(ATTR_TMPFS, default=False): vol.Boolean(), vol.Optional(ATTR_TMPFS, default=False): vol.Boolean(),
vol.Optional(ATTR_MAP, default=list): [vol.Match(RE_VOLUME)], vol.Optional(ATTR_MAP, default=list): [vol.Match(RE_VOLUME)],
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): str}, vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): str},
vol.Optional(ATTR_PRIVILEGED): [vol.In(PRIVILEGED_ALL)], vol.Optional(ATTR_PRIVILEGED): [vol.Coerce(Capabilities)],
vol.Optional(ATTR_APPARMOR, default=True): vol.Boolean(), vol.Optional(ATTR_APPARMOR, default=True): vol.Boolean(),
vol.Optional(ATTR_FULL_ACCESS, default=False): vol.Boolean(), vol.Optional(ATTR_FULL_ACCESS, default=False): vol.Boolean(),
vol.Optional(ATTR_AUDIO, default=False): vol.Boolean(), vol.Optional(ATTR_AUDIO, default=False): vol.Boolean(),

View File

@ -328,30 +328,6 @@ SECURITY_PROFILE = "profile"
SECURITY_DEFAULT = "default" SECURITY_DEFAULT = "default"
SECURITY_DISABLE = "disable" SECURITY_DISABLE = "disable"
PRIVILEGED_DAC_READ_SEARCH = "DAC_READ_SEARCH"
PRIVILEGED_IPC_LOCK = "IPC_LOCK"
PRIVILEGED_NET_ADMIN = "NET_ADMIN"
PRIVILEGED_SYS_ADMIN = "SYS_ADMIN"
PRIVILEGED_SYS_MODULE = "SYS_MODULE"
PRIVILEGED_SYS_NICE = "SYS_NICE"
PRIVILEGED_SYS_PTRACE = "SYS_PTRACE"
PRIVILEGED_SYS_RAWIO = "SYS_RAWIO"
PRIVILEGED_SYS_RESOURCE = "SYS_RESOURCE"
PRIVILEGED_SYS_TIME = "SYS_TIME"
PRIVILEGED_ALL = [
PRIVILEGED_NET_ADMIN,
PRIVILEGED_SYS_ADMIN,
PRIVILEGED_SYS_RAWIO,
PRIVILEGED_IPC_LOCK,
PRIVILEGED_SYS_TIME,
PRIVILEGED_SYS_NICE,
PRIVILEGED_SYS_RESOURCE,
PRIVILEGED_SYS_PTRACE,
PRIVILEGED_SYS_MODULE,
PRIVILEGED_DAC_READ_SEARCH,
]
ROLE_DEFAULT = "default" ROLE_DEFAULT = "default"
ROLE_HOMEASSISTANT = "homeassistant" ROLE_HOMEASSISTANT = "homeassistant"
ROLE_BACKUP = "backup" ROLE_BACKUP = "backup"

View File

@ -6,7 +6,7 @@ from ipaddress import IPv4Address, ip_address
import logging import logging
import os import os
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Union from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Set, Union
from awesomeversion import AwesomeVersion from awesomeversion import AwesomeVersion
import docker import docker
@ -31,6 +31,7 @@ from ..exceptions import CoreDNSError, DockerError, DockerNotFound, HardwareNotF
from ..hardware.const import PolicyGroup from ..hardware.const import PolicyGroup
from ..resolution.const import ContextType, IssueType, SuggestionType from ..resolution.const import ContextType, IssueType, SuggestionType
from ..utils import process_lock from ..utils import process_lock
from .const import Capabilities
from .interface import DockerInterface from .interface import DockerInterface
if TYPE_CHECKING: if TYPE_CHECKING:
@ -225,6 +226,20 @@ class DockerAddon(DockerInterface):
return "host" return "host"
return None return None
@property
def capabilities(self) -> Optional[List[str]]:
"""Generate needed capabilities."""
capabilities: Set[Capabilities] = set(self.addon.privileged)
# Need work with kernel modules
if self.addon.with_kernel_modules:
capabilities.add(Capabilities.SYS_MODULE)
# Return None if no capabilities is present
if capabilities:
return [cap.value for cap in capabilities]
return None
@property @property
def volumes(self) -> Dict[str, Dict[str, str]]: def volumes(self) -> Dict[str, Dict[str, str]]:
"""Generate volumes for mappings.""" """Generate volumes for mappings."""
@ -386,7 +401,7 @@ class DockerAddon(DockerInterface):
ports=self.ports, ports=self.ports,
extra_hosts=self.network_mapping, extra_hosts=self.network_mapping,
device_cgroup_rules=self.cgroups_rules, device_cgroup_rules=self.cgroups_rules,
cap_add=self.addon.privileged, cap_add=self.capabilities,
security_opt=self.security_opt, security_opt=self.security_opt,
environment=self.environment, environment=self.environment,
volumes=self.volumes, volumes=self.volumes,

View File

@ -0,0 +1,17 @@
"""Docker constants."""
from enum import Enum
class Capabilities(str, Enum):
"""Linux Capabilities."""
DAC_READ_SEARCH = "DAC_READ_SEARCH"
IPC_LOCK = "IPC_LOCK"
NET_ADMIN = "NET_ADMIN"
SYS_ADMIN = "SYS_ADMIN"
SYS_MODULE = "SYS_MODULE"
SYS_NICE = "SYS_NICE"
SYS_PTRACE = "SYS_PTRACE"
SYS_RAWIO = "SYS_RAWIO"
SYS_RESOURCE = "SYS_RESOURCE"
SYS_TIME = "SYS_TIME"