-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
linux
: Support setting execution domain via linux personality
.
#3126
Conversation
utils_linux.go
Outdated
@@ -272,6 +273,13 @@ func (r *runner) run(config *specs.Process) (int, error) { | |||
if err = r.checkTerminal(config); err != nil { | |||
return -1, err | |||
} | |||
// configure linux personality | |||
if r.container.Config().Personality != nil { | |||
err = setLinuxPersonality(r.container.Config().Personality.Domain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we fail
for this err ? I low-key want to ignore this err if syscall.SYS_PERSONALITY
fails proceed as if nothing happened. I'll probably wait for mods to suggest here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failing seems better for security.
I guess we should also fail when unknown Personality.Flags
are set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AkihiroSuda Cool i agree it makes sense from security perspective so i will let the check be there. For Personality.Flags
i did not implement it as runtime-spec
suggests that no flag values are supported as well as domain is limited to LINUX
and LINUX32
. So anything unknown defaults to LINUX
i.e 0x0000
.
@flouthoc can you describe the use case? I thought it's for starting i386 binaries but they work as is. I think internally it's better to represent the personality value as a number rather than a string. |
This should shed some light: opencontainers/runtime-spec@5cc25d0 crun support: containers/crun@afc183b |
e787337
to
cb03125
Compare
@kolyshkin the commit you shared describes the edge-case but I also think that build for any Also added as comment here https://github.com/opencontainers/runc/pull/3126/files#diff-96def2e006cb3518f1aaf9a595a80648521905e352e625550bff15aaa0019fa0R404
For this personalty is defined as number const (
PER_LINUX = 0x0000
PER_LINUX32 = 0x0008
) |
It's kind of weird that
But I guess it is what it is. |
I didn't mean to change the runtime spec. What I meant is we're converting the spec into our internal presentation anyway (in libcontainer/specconv), and this is where, I think, we should do a string -> number translation. |
a856ea2
to
e6bcfd3
Compare
@kolyshkin Applied requested changes could you please review again. |
@AkihiroSuda @kolyshkin We would also need downstream pr on managers / shims to support this. containers/podman#11141 |
@kolyshkin anything else which needs to be done from my side. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of nits, and we need a test case.
e6bcfd3
to
050289d
Compare
@kolyshkin Could you please take a look again ? resolved the feedback comments and added integration tests. Also changed the approach a little bit.
|
050289d
to
4600cdd
Compare
@kolyshkin Squeezed personality tests with exec integration tests, let me know if separate file needs to created. |
@kolyshkin were you able to take a look at this, is there anything else with needs to be done from my side |
Signed-off-by: Aditya Rajan <flouthoc.git@gmail.com>
828567b
to
aab68b3
Compare
@@ -230,6 +230,13 @@ func (c *linuxContainer) Set(config configs.Config) error { | |||
func (c *linuxContainer) Start(process *Process) error { | |||
c.m.Lock() | |||
defer c.m.Unlock() | |||
// configure linux personality before starting the process | |||
if c.config.Personality != nil { | |||
err := system.SetLinuxPersonality(c.config.Personality.Domain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still unsure this is the best place. @cyphar can you please take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we want to set personality as soon as process starts so this seems the best place to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, here you set it before the process starts, not as soon as.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for confusion i meant this should happen just before the process start or as soon as the process start so execution happens in configured execution domain. But i am cool if you think there is any better place for this call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super familiar with personalities to be honest, my guess is that we would want to do this as close to execve as possible since I don't know what effect setting the personality will have to runc's internal code. As such, I would suggest this should probably happen as close to execve as possible -- that would mean in standard_init_linux.go
and setns_init_linux.go
-- right before we apply seccomp filters probably.
@flouthoc When talking about the "process start" -- this code is being run very early in container setup. Do you mean that we need to set this way before the users' code has even started executing (I would've thought we only need to set it right before we execve the users' binary)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cyphar I actually tried it in standard_init_linux.go
a while ago for some reasons I don't exactly recall i was having some issues, something something on the lines of goroutines and because of it personality tests were failing. I'll try it again and post insights thanks.
// check libcontainer/configs/config_linux.go | ||
// check https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/personality.h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to add these references each time.
func getLinuxPersonalityFromStr(domain string) int { | ||
// defaults to PER_LINUX | ||
if domain == "LINUX32" { | ||
return configs.PER_LINUX32 | ||
} | ||
return configs.PER_LINUX | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should ignore strange settings -- this is just going to cause nightmares for backwards compatibility. Since getLinuxPersonalityFromStr
will only be called if a user has explicitly specified a personality, we should definitely return an error if the personality name is meaningless.
func TestPersonality(t *testing.T) { | ||
if testing.Short() { | ||
return | ||
} | ||
|
||
config := newTemplateConfig(t, &tParam{}) | ||
|
||
// change execution domain to i686 | ||
config.Personality = &configs.LinuxPersonality{ | ||
Domain: configs.PER_LINUX32, | ||
} | ||
|
||
out, _, err := runContainer(t, config, "", "/bin/sh", "-c", "uname -a") | ||
ok(t, err) | ||
// output must contain kernel architecture configured as i686 | ||
if !strings.Contains(out.Stdout.String(), "i686") { | ||
t.Fatalf("expected kernel architecture i686 configured via personality") | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for future reference -- I would prefer a bats-based integration test, but since you've already written this one, don't worry about it.
@@ -230,6 +230,13 @@ func (c *linuxContainer) Set(config configs.Config) error { | |||
func (c *linuxContainer) Start(process *Process) error { | |||
c.m.Lock() | |||
defer c.m.Unlock() | |||
// configure linux personality before starting the process | |||
if c.config.Personality != nil { | |||
err := system.SetLinuxPersonality(c.config.Personality.Domain) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super familiar with personalities to be honest, my guess is that we would want to do this as close to execve as possible since I don't know what effect setting the personality will have to runc's internal code. As such, I would suggest this should probably happen as close to execve as possible -- that would mean in standard_init_linux.go
and setns_init_linux.go
-- right before we apply seccomp filters probably.
@flouthoc When talking about the "process start" -- this code is being run very early in container setup. Do you mean that we need to set this way before the users' code has even started executing (I would've thought we only need to set it right before we execve the users' binary)?
@flouthoc Could you update the PR? |
@flouthoc do you still want to work on this one? If yes, can you please rebase? |
@kolyshkin @AkihiroSuda @cyphar Hello guys, this PR seems been deprecated for a while. may I take handle of it and carry it? |
Yes, please |
Closing this PR in favor of above discussion. @Zheaoli Could you please open a new PR for this, feel free to copy whatever code is needed as it is or change parts as per needs i'm not sure if its code in this PR is updated as per recent runc version but hope it works. |
Of course, thanks for your work! |
@Zheaoli Do you plan to open a new PR? |
Yes I will open a new PR this weekend |
…a linux personality Signed-off-by: Zheao.Li <me@manjusaka.me>
…a linux personality Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
…a linux personality Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
…a linux personality Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry opencontainers#3126 Co-authored-by: Aditya R <arajan@redhat.com> Signed-off-by: Zheao.Li <me@manjusaka.me>
carry #3126: linux: Support setting execution domain via linux personality
Hi Team,
Following PR allows users to configure execution domain via
syscall.SYS_PERSONALITY
.Valid inputs supported via spec are limited to
LINUX
andLINUX32
.References:
https://man7.org/linux/man-pages/man2/personality.2.html
https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/personality.h