-
Notifications
You must be signed in to change notification settings - Fork 246
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
unshare: improve rootless detection #1312
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import ( | |
"errors" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"os/signal" | ||
|
@@ -387,10 +388,39 @@ const ( | |
UsernsEnvName = "_CONTAINERS_USERNS_CONFIGURED" | ||
) | ||
|
||
// hasFullUsersMappings checks whether the current user namespace has all the IDs mapped. | ||
func hasFullUsersMappings() (bool, error) { | ||
content, err := ioutil.ReadFile("/proc/self/uid_map") | ||
if err != nil { | ||
return false, err | ||
} | ||
// if the uid_map contains 4294967295, the entire IDs space is available in the | ||
// user namespace, so it is likely the initial user namespace. | ||
return bytes.Contains(content, []byte("4294967295")), nil | ||
mtrmac marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// IsRootless tells us if we are running in rootless mode | ||
func IsRootless() bool { | ||
isRootlessOnce.Do(func() { | ||
isRootless = getRootlessUID() != 0 || getenv(UsernsEnvName) != "" | ||
if !isRootless { | ||
hasCapSysAdmin, err := HasCapSysAdmin() | ||
if err != nil { | ||
logrus.Warnf("Failed to read CAP_SYS_ADMIN presence for the current process") | ||
} | ||
if err == nil && !hasCapSysAdmin { | ||
isRootless = true | ||
} | ||
} | ||
if !isRootless { | ||
hasMappings, err := hasFullUsersMappings() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would this indicate isRootless. If I have a range of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But we are using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think by now, we desperately need documentation. “IsRootless tells us if we are running in rootless mode” says nothing. Describe in which situations that function returns true (possibly how can one get into such situations), and what does that means for application behavior. What should, or shouldn’t, they be doing differently? It might well be the case that we need three or more different functions, Just vaguely saying “rootless” is apparently causing misunderstandings and unanticipated breakage. |
||
if err != nil { | ||
logrus.Warnf("Failed to read current user namespace mappings") | ||
} | ||
if err == nil && !hasMappings { | ||
isRootless = true | ||
} | ||
} | ||
}) | ||
return isRootless | ||
} | ||
|
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.
This comment doesn't seem to describe what's happening before or after it, so I don't understand what's happening 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.
I've fixed the comment and pushed a new version