Skip to content

RFC: introduce SetProcessKind #266

Description

@kolyshkin

OK, I found out a somewhat weird thing (which I wish to find earlier than today). NOTE this is a continuation of #247 (comment)

All (open source) users of selinux.KVMContainerLabel[s] and selinux.InitContainerLabel[s] are immediately releasing the acquired MCS. They only use the type field. Here are all the users:

What happens is we generate uniq MCS which gets released immediately! The only used field is type.

So I think here in selinux we don't need KVMContainerLabel[s], InitContainerLabel[s] etc.

We only need something like this:

type ContainerLabelType int

const (
  ContainerProcess ContainerLabelKind = iota // Corresponds to "process" label.
  ContainerInitProcess // ... "init_process" label.
  ContainerKVMProcess // ... "kvm_process" label.
)

func (k ContainerLabelType) configKey() (primary, fallback string, ok bool) {                                                                                                                                                 
      switch k {  
      case ContainerProcess:                                                                                                                                                                                                    
          return "process", "", true
      case ContainerInitProcess:
          return "init_process", "process", true
      case ContainerKVMProcess:                                                                                                                                                                                                 
          return "kvm_process", "process", true
      }                                                                                                                                                                                                                         
      return "", "", false
}

func ChangeContainerLabelType(cLabel string, type ContainerLabelType) (string, error) {
      if cLabel == "" {                                                                                                                                                                                                         
          return "", nil
      }                                                                                                                                                                                                                         
      primary, fallback, ok := kind.configKey()
      if !ok {                                                                                                                                                                                                                  
          return "", fmt.Errorf("selinux: invalid ContainerLabelKind %d", kind)
      }                                                                                                                                                                                                                         
                                                                                                                                                                                                                                
      src := label(primary)
      if src == "" && fallback != "" {                                                                                                                                                                                          
          src = label(fallback)
      }                                                                                                                                                                                                                         
      if src == "" {
          return cLabel, nil                                                                                                                                                                                                    
      }           

      srcCtx, err := newContext(src)
      if err != nil {
          return "", err                                                                                                                                                                                                        
      }
      dstCtx, err := newContext(cLabel)                                                                                                                                                                                         
      if err != nil {
          return "", err
      }
      dstCtx["type"] = srcCtx["type"]
      return dstCtx.Get(), nil 
}

Then the users are simplified to (using podman as an example)

// KVMLabel returns labels for running kvm isolated containers
func KVMLabel(cLabel string) (string, error) {
   return selinux.ChangeContainerLabelType(cLabel, selinux.ContainerKVMProcess)
}

// InitLabel returns labels for running systemd based containers.
func InitLabel(cLabel string) (string, error) {
   return selinux.ChangeContainerLabelType(cLabel, selinux.ContainerInitProcess)
}

cri-o and containerd change is similar. Most importantly, this will remove unneeded and expensive "generate and reserve MCS labels to immediately discard those".

@rhatdan @thaJeztah what do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions