Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Add seccomp feature #529

Closed
wants to merge 5 commits into from
Closed

Add seccomp feature #529

wants to merge 5 commits into from

Conversation

keloyang
Copy link
Contributor

add seccomp feature which is not use third-party
add multi arch surport
add test case
all code use golang

this pr is relate to #511 because I close it and find it can not be reopen

Signed-off-by: Yang Shukui [email protected]

@hqhq
Copy link
Contributor

hqhq commented Apr 14, 2015

@pcmoore Can we discuss it in it's own thread?
commends from pcmoore:

Interesting, it handles the seccomp BPF filter generation completely in Golang. I'm obviously a little biased so I won't comment on which approach is better, but I will mention that just a quick glance at the code in PR #529 revealed a few issues/concerns:

It doesn't appear that x32 is handled correctly, resulting in a gap in protection on some systems

  • The syscall tables are wrong for ARM, e.g. OABI_SYSCALL_BASE (?)
  • The code doesn't abstract away architecture specifics, e.g. socketcall()
  • The generated BPF filter code looks like it might be twice as large as necessary resulting in unnecessary per-syscall performance overhead
  • The generated BPF filter code has a trap/signal return action, yet I don't see a signal handler defined (?) ... possible this may be misunderstanding how Golang handles signals

I suspect if I look closer there are more issues as well, not to mention the long term maintenence issues (who will keep the syscall tables updated?).

@hqhq
Copy link
Contributor

hqhq commented Apr 14, 2015

Code review is a bit earlier, surely there would be lots of improvement for the code, I think we can have a design review first, have a comparison between these two approaches before we merge any of them.

I think maintaining syscall tables is acceptable, it's quite stable now, and we already maintain other kernel related info, like rlimit, capability etc, so that won't be the problem.

ping @crosbymichael

@pcmoore
Copy link

pcmoore commented Apr 14, 2015

I'll leave the code review to you guys as you are much more knowledgeable than I am about Golang, but I will advise you to carefully examine the generated BPF code from both approaches as well as consider how you would support a single Docker filter configuration across multiple platforms (e.g. the x86 socketcall() problem).

@keloyang
Copy link
Contributor Author

@pcmoore
thanks for your review.

The syscall tables are wrong for ARM, e.g. OABI_SYSCALL_BASE (?)

  • for arm, we don't use SYS_OABI_SYSCALL_BASE and SYS_SYSCALL_BASE, just start from SYS_RESTART_SYSCALL. and for multible arch, we can just relate to golang syscall,and relate to golang source code, e.g. syscall zsysnum_linux_arm.go/zsysnum_linux_386.go etc.

The code doesn't abstract away architecture specifics, e.g. socketcall()

  • I misunderstand, you means uniform interface for 386/arm/amd64 etc. or other ?

The generated BPF filter code looks like it might be twice as large as necessary resulting in unnecessary per-syscall performance overhead

  • It is a problem ? BPF is complex, but can be used simply, we can have a reference for kernel/example/seccomp

The generated BPF filter code has a trap/signal return action, yet I don't see a signal handler defined (?) ... possible this may be misunderstanding how Golang handles signals

  • SECCOMP_RET_KILL has a precedence for SECCOMP_RET_TRAP, we can relate to https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt. SECCOMP_RET_KILL: Results in the task exiting immediately without executing the system call.
    SECCOMP_RET_TRAP: Results in the kernel sending a SIGSYS signal to the triggeringtask without executing the system call. for SECCOMP_RET_KILL, I don't think a signal action is necessary. WDYT?

@hqhq +1 I think maintaining syscall tables is acceptable

@pcmoore
Copy link

pcmoore commented Apr 16, 2015

A few follow-ups:

  • Regarding OABI_SYSCALL_BASE: I think there is a misunderstanding, let me try again - why do you define OABI_SYSCALL_BASE as a syscall in the ARM syscall table? That seems to be incorrect to me.
  • Regarding arch/ABI abstractions: How do you handle a configuration that involves socket() on x86? How do you handle socketcall() on ARM? Abstracting away the arch/ABI specifics is important to keeping a consistent configuration.
  • Yes, larger wasteful BPF programs are large and wasteful, especially when it is called on each syscall invocation.
  • I still don't understand why you are returning SECCOMP_RET_TRAP without a signal handler, that just doesn't make sense.

@keloyang
Copy link
Contributor Author

  • Regarding OABI_SYSCALL_BASE: I think there is a misunderstanding, let me try again - why do you define OABI_SYSCALL_BASE as a syscall in the ARM syscall table? That seems to be incorrect to me.
    OABI_SYSCALL_BASE may bring misunderstanding, I will remote it.
  • Regarding arch/ABI abstractions: How do you handle a configuration that involves socket() on x86? How do you handle socketcall() on ARM? Abstracting away the arch/ABI specifics is important to keeping a consistent configuration.
    It's really a big problem. for i386, socket() is arg for socketcall(), adding the args surport can resolve these problem. Regrettably, it not surport now. I will add arg surporting later.
  • Yes, larger wasteful BPF programs are large and wasteful, especially when it is called on each syscall invocation.
  • I still don't understand why you are returning SECCOMP_RET_TRAP without a signal handler, that just doesn't make sense.
    SECCOMP_RET_TRAP doesn't make sense, remote it.

thanks for your follow-ups!

@crosbymichael
Copy link
Contributor

@keloyang do you have the code that generates these tables?

@crosbymichael
Copy link
Contributor

Can you disable certain flags passed to syscalls with this implementation. Like preventing the CLONE_NEW* flags to clone()?

@keloyang
Copy link
Contributor Author

@crosbymichael
sorry for my late reply.

I have change ScmpAdd(ctx *ScmpCtx, call sting ... to ScmpAdd(ctx *ScmpCtx, call int ... , we can use lxc seccomp config file now( refer to TestSeccompNotStat), and seccomp enable flags is added for easy control.

though the local test of libcontainner is past, but docker can't use it except adding this to default config(refer to newTemplateConfig):
Seccomps: configs.SeccompConf{
Enable: false,
SysCalls: make([]int, 0, 512),
},

@crosbymichael
Copy link
Contributor

@keloyang what about arguments to the specific syscalls?

@keloyang
Copy link
Contributor Author

keloyang commented May 2, 2015

@crosbymichael, the code don't surport for arguments, and I'm doing this.

@LK4D4
Copy link
Contributor

LK4D4 commented May 16, 2015

@keloyang Looks like rebase is needed :/

@crosbymichael
Copy link
Contributor

@keloyang i guess one of the goals with seccomp support is to be able to prevent the CLONE_NEWUSER flag being passed to clone(). Is this hard to do?

@pcmoore
Copy link

pcmoore commented May 21, 2015

Blocking clone(CLONE_NEWUSER) is possible with libseccomp and the SCMP_CMP_MASKED_EQ comparison operator.

@keloyang
Copy link
Contributor Author

@crosbymichael @LK4D4
I have rebased and add args surport; CLONE_SECCOMP is also added which is like to CLOEN_IPC.

@LK4D4
Copy link
Contributor

LK4D4 commented May 22, 2015

@keloyang

seccomp/seccomp.go:331: undefined: syscallMap

Thanks for your work! It's amazing.

@keloyang
Copy link
Contributor Author

maybe "chmod 755 hack/seccomp.sh" work!

@@ -0,0 +1,56 @@
#!/usr/bin/perl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want I can help you rewrite this on go and use go generate for generating. So, developers won't be dependent on golang.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, of course you should commit generated code and not rely on generation tool. It is pretty hard to track bugs this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I'll prepare PR to your PR.

@LK4D4
Copy link
Contributor

LK4D4 commented May 22, 2015

@keloyang There is no seccomp_main in your PR.

@@ -169,6 +169,13 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, c
cmd.SysProcAttr.Credential = &syscall.Credential{}
}
}
if cloneFlags&uintptr(configs.CLONE_SECCOMP) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be done by client. Silently ignore security issue isn't good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crosbymichael @LK4D4

  • Can you disable certain flags passed to syscalls with this implementation. Like preventing the CLONE_NEW* flags to clone()?
    kernel don' surport for CLONE_SECCOMP, it is a pseudo flag which give a way to enable the seccomp feature. I misunderstand ?

@LK4D4
Copy link
Contributor

LK4D4 commented May 22, 2015

Hmm, it's weird to have sec.Sys. We should accept []string as syscall then. Or just rely on client with string -> syscall conversion.

@@ -4,17 +4,22 @@ package configs

import "syscall"

var (
CLONE_SECCOMP = 0x10000 //diffrent from other flag, hard code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually CLONE_NEWUSER. Why we need this at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLONE_NEWUSER = 0x10000000
CLONE_NEWSECCOMP is a pseudo flag, which is diffrent other CLONE_xx flag, and it can not pass to clone.

yangshukui and others added 5 commits June 4, 2015 04:01
add seccomp feature which is not use third-party
add multi arch surport
add test case
all code use golang

this pr is relate to #511 because I close it and find it can not be reopen

Signed-off-by: Yang Shukui <[email protected]>
    1. add args surport for seccomp
    2. add CLONE_SECCOMP flag for preventing seccomp feature
Signed-off-by: Yang Shukui <[email protected]>
Signed-off-by: Yang Shukui <[email protected]>
add the generated go file
Signed-off-by: Yang Shukui <[email protected]>
add maskequal surport
Signed-off-by: Yang Shukui <[email protected]>
@crosbymichael
Copy link
Contributor

#613 was merged with your changes

thanks again for all your help

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants