mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
This patch reworks the SELinux patch to be only run on demand by the daemon
Added --selinux-enable switch to daemon to enable SELinux labeling. The daemon will now generate a new unique random SELinux label when a container starts, and remove it when the container is removed. The MCS labels will be stored in the daemon memory. The labels of containers will be stored in the container.json file. When the daemon restarts on boot or if done by an admin, it will read all containers json files and reserve the MCS labels. A potential problem would be conflicts if you setup thousands of containers, current scheme would handle ~500,000 containers. Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: rhatdan) Docker-DCO-1.1-Signed-off-by: Dan Walsh <dwalsh@redhat.com> (github: crosbymichael)
This commit is contained in:
parent
f0e6e135a8
commit
b7942ec2ca
8 changed files with 50 additions and 14 deletions
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/dotcloud/docker/image"
|
"github.com/dotcloud/docker/image"
|
||||||
"github.com/dotcloud/docker/links"
|
"github.com/dotcloud/docker/links"
|
||||||
"github.com/dotcloud/docker/nat"
|
"github.com/dotcloud/docker/nat"
|
||||||
"github.com/dotcloud/docker/pkg/selinux"
|
"github.com/dotcloud/docker/pkg/label"
|
||||||
"github.com/dotcloud/docker/runconfig"
|
"github.com/dotcloud/docker/runconfig"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
"io"
|
"io"
|
||||||
|
@ -66,7 +66,7 @@ type Container struct {
|
||||||
stdinPipe io.WriteCloser
|
stdinPipe io.WriteCloser
|
||||||
|
|
||||||
daemon *Daemon
|
daemon *Daemon
|
||||||
mountLabel, processLabel string
|
MountLabel, ProcessLabel string
|
||||||
|
|
||||||
waitLock chan struct{}
|
waitLock chan struct{}
|
||||||
Volumes map[string]string
|
Volumes map[string]string
|
||||||
|
@ -124,6 +124,7 @@ func (container *Container) FromDisk() error {
|
||||||
if err := json.Unmarshal(data, container); err != nil && !strings.Contains(err.Error(), "docker.PortMapping") {
|
if err := json.Unmarshal(data, container); err != nil && !strings.Contains(err.Error(), "docker.PortMapping") {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
label.ReserveLabel(container.ProcessLabel)
|
||||||
return container.readHostConfig()
|
return container.readHostConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +326,8 @@ func populateCommand(c *Container, env []string) {
|
||||||
en *execdriver.Network
|
en *execdriver.Network
|
||||||
context = make(map[string][]string)
|
context = make(map[string][]string)
|
||||||
)
|
)
|
||||||
context["process_label"] = []string{c.processLabel}
|
context["process_label"] = []string{c.ProcessLabel}
|
||||||
context["mount_label"] = []string{c.mountLabel}
|
context["mount_label"] = []string{c.MountLabel}
|
||||||
|
|
||||||
en = &execdriver.Network{
|
en = &execdriver.Network{
|
||||||
Mtu: c.daemon.config.Mtu,
|
Mtu: c.daemon.config.Mtu,
|
||||||
|
@ -388,10 +389,13 @@ func (container *Container) Start() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
process, mount := selinux.GetLxcContexts()
|
process, mount, err := label.GenLabels("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
container.mountLabel = mount
|
container.MountLabel = mount
|
||||||
container.processLabel = process
|
container.ProcessLabel = process
|
||||||
|
|
||||||
if err := container.Mount(); err != nil {
|
if err := container.Mount(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -289,6 +289,8 @@ func (daemon *Daemon) Destroy(container *Container) error {
|
||||||
if err := os.RemoveAll(container.root); err != nil {
|
if err := os.RemoveAll(container.root); err != nil {
|
||||||
return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
|
return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
|
||||||
}
|
}
|
||||||
|
selinux.FreeLxcContexts(container.ProcessLabel)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +841,7 @@ func (daemon *Daemon) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) Mount(container *Container) error {
|
func (daemon *Daemon) Mount(container *Container) error {
|
||||||
dir, err := daemon.driver.Get(container.ID, container.mountLabel)
|
dir, err := daemon.driver.Get(container.ID, container.MountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
|
return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ func ConfigFromJob(job *engine.Job) *Config {
|
||||||
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
||||||
GraphDriver: job.Getenv("GraphDriver"),
|
GraphDriver: job.Getenv("GraphDriver"),
|
||||||
ExecDriver: job.Getenv("ExecDriver"),
|
ExecDriver: job.Getenv("ExecDriver"),
|
||||||
EnableSelinuxSupport: job.GetenvBool("SelinuxEnabled"),
|
EnableSelinuxSupport: job.GetenvBool("EnableSelinuxSupport"),
|
||||||
}
|
}
|
||||||
if dns := job.GetenvList("Dns"); dns != nil {
|
if dns := job.GetenvList("Dns"); dns != nil {
|
||||||
config.Dns = dns
|
config.Dns = dns
|
||||||
|
|
|
@ -149,7 +149,7 @@ func main() {
|
||||||
job.Setenv("GraphDriver", *flGraphDriver)
|
job.Setenv("GraphDriver", *flGraphDriver)
|
||||||
job.Setenv("ExecDriver", *flExecDriver)
|
job.Setenv("ExecDriver", *flExecDriver)
|
||||||
job.SetenvInt("Mtu", *flMtu)
|
job.SetenvInt("Mtu", *flMtu)
|
||||||
job.SetenvBool("SelinuxEnabled", *flSelinuxEnabled)
|
job.SetenvBool("EnableSelinuxSupport", *flSelinuxEnabled)
|
||||||
if err := job.Run(); err != nil {
|
if err := job.Run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,3 +24,7 @@ func GetPidCon(pid int) (string, error) {
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReserveLabel(label string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -75,3 +75,7 @@ func GetPidCon(pid int) (string, error) {
|
||||||
func Init() {
|
func Init() {
|
||||||
selinux.SelinuxEnabled()
|
selinux.SelinuxEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReserveLabel(label string) {
|
||||||
|
selinux.ReserveLabel(label)
|
||||||
|
}
|
||||||
|
|
|
@ -204,6 +204,13 @@ func NewContext(scon string) SELinuxContext {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReserveLabel(scon string) {
|
||||||
|
if len(scon) != 0 {
|
||||||
|
con := strings.SplitN(scon, ":", 4)
|
||||||
|
mcsAdd(con[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func SelinuxGetEnforce() int {
|
func SelinuxGetEnforce() int {
|
||||||
var enforce int
|
var enforce int
|
||||||
|
|
||||||
|
@ -229,8 +236,12 @@ func SelinuxGetEnforceMode() int {
|
||||||
return Disabled
|
return Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func mcsAdd(mcs string) {
|
func mcsAdd(mcs string) error {
|
||||||
|
if mcsList[mcs] {
|
||||||
|
return fmt.Errorf("MCS Label already exists")
|
||||||
|
}
|
||||||
mcsList[mcs] = true
|
mcsList[mcs] = true
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mcsDelete(mcs string) {
|
func mcsDelete(mcs string) {
|
||||||
|
@ -283,15 +294,21 @@ func uniqMcs(catRange uint32) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2)
|
mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2)
|
||||||
if mcsExists(mcs) {
|
if err := mcsAdd(mcs); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mcsAdd(mcs)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return mcs
|
return mcs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FreeLxcContexts(scon string) {
|
||||||
|
if len(scon) != 0 {
|
||||||
|
con := strings.SplitN(scon, ":", 4)
|
||||||
|
mcsDelete(con[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetLxcContexts() (processLabel string, fileLabel string) {
|
func GetLxcContexts() (processLabel string, fileLabel string) {
|
||||||
var (
|
var (
|
||||||
val, key string
|
val, key string
|
||||||
|
@ -344,7 +361,8 @@ func GetLxcContexts() (processLabel string, fileLabel string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
mcs := IntToMcs(os.Getpid(), 1024)
|
// mcs := IntToMcs(os.Getpid(), 1024)
|
||||||
|
mcs := uniqMcs(1024)
|
||||||
scon := NewContext(processLabel)
|
scon := NewContext(processLabel)
|
||||||
scon["level"] = mcs
|
scon["level"] = mcs
|
||||||
processLabel = scon.Get()
|
processLabel = scon.Get()
|
||||||
|
@ -373,6 +391,8 @@ func CopyLevel(src, dest string) (string, error) {
|
||||||
}
|
}
|
||||||
scon := NewContext(src)
|
scon := NewContext(src)
|
||||||
tcon := NewContext(dest)
|
tcon := NewContext(dest)
|
||||||
|
mcsDelete(tcon["level"])
|
||||||
|
mcsAdd(scon["level"])
|
||||||
tcon["level"] = scon["level"]
|
tcon["level"] = scon["level"]
|
||||||
return tcon.Get(), nil
|
return tcon.Get(), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,11 @@ func TestSELinux(t *testing.T) {
|
||||||
plabel, flabel = selinux.GetLxcContexts()
|
plabel, flabel = selinux.GetLxcContexts()
|
||||||
t.Log(plabel)
|
t.Log(plabel)
|
||||||
t.Log(flabel)
|
t.Log(flabel)
|
||||||
|
selinux.FreeLxcContexts(plabel)
|
||||||
plabel, flabel = selinux.GetLxcContexts()
|
plabel, flabel = selinux.GetLxcContexts()
|
||||||
t.Log(plabel)
|
t.Log(plabel)
|
||||||
t.Log(flabel)
|
t.Log(flabel)
|
||||||
|
selinux.FreeLxcContexts(plabel)
|
||||||
t.Log("getenforce ", selinux.SelinuxGetEnforce())
|
t.Log("getenforce ", selinux.SelinuxGetEnforce())
|
||||||
t.Log("getenforcemode ", selinux.SelinuxGetEnforceMode())
|
t.Log("getenforcemode ", selinux.SelinuxGetEnforceMode())
|
||||||
pid := os.Getpid()
|
pid := os.Getpid()
|
||||||
|
|
Loading…
Reference in a new issue