{"action":"created","comment":{"url":"https://api.github.com/repos/opencontainers/runc/pulls/comments/61011863","id":61011863,"diff_hunk":"@@ -0,0 +1,100 @@\n+package validate\n+\n+import (\n+\t\"fmt\"\n+\t\"reflect\"\n+\t\"strings\"\n+\n+\t\"github.com/opencontainers/runc/libcontainer/configs\"\n+)\n+\n+type RootlessValidator struct {\n+}\n+\n+func (v *RootlessValidator) Validate(config *configs.Config) error {\n+\t// There's nothing to validate.\n+\tif config == nil {\n+\t\treturn nil\n+\t}\n+\n+\tif err := v.mount(config); err != nil {\n+\t\treturn err\n+\t}\n+\t// If we're running under Linux with CLONE_NEWCGROUP, we don't have to worry\n+\t// about any of this.\n+\tif !config.Namespaces.Contains(configs.NEWCGROUP) {\n+\t\tif err := v.cgroup(config); err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t}\n+\n+\t// XXX: We currently can't verify the user config at all, because\n+\t//      configs.Config doesn't store the user-related configs. So this\n+\t//      has to be verified by setupUser() in init_linux.go.\n+\n+\treturn nil\n+}\n+\n+// cgroup verifies that the user isn't trying to set any cgroup limits or paths.\n+func (v *RootlessValidator) cgroup(config *configs.Config) error {\n+\t// Nothing set at all.\n+\tif config.Cgroups == nil || config.Cgroups.Resources == nil {\n+\t\treturn nil\n+\t}\n+\n+\t// Used for comparison.","path":"libcontainer/configs/validate/rootless.go","position":45,"original_position":45,"commit_id":"43e810aaac48c340218f4565d0d8a2d62b1a91e3","original_commit_id":"43e810aaac48c340218f4565d0d8a2d62b1a91e3","user":{"login":"cyphar","id":2888411,"avatar_url":"https://avatars.githubusercontent.com/u/2888411?v=3","gravatar_id":"","url":"https://api.github.com/users/cyphar","html_url":"https://github.com/cyphar","followers_url":"https://api.github.com/users/cyphar/followers","following_url":"https://api.github.com/users/cyphar/following{/other_user}","gists_url":"https://api.github.com/users/cyphar/gists{/gist_id}","starred_url":"https://api.github.com/users/cyphar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cyphar/subscriptions","organizations_url":"https://api.github.com/users/cyphar/orgs","repos_url":"https://api.github.com/users/cyphar/repos","events_url":"https://api.github.com/users/cyphar/events{/privacy}","received_events_url":"https://api.github.com/users/cyphar/received_events","type":"User","site_admin":false},"body":"The current state of this patchset doesn't modify the config inside `libcontainer`. The issue is that `specconv` adds device options to `[]Device` even if the user doesn't specify anything. So we can either do the verification of the cgroups in runC (which means that if someone uses libcontainer directly they probably won't immediately realise they can't set cgroup settings) or we do the verification in libcontainer and make `specconv` not generate any cgroup options in rootless mode.","created_at":"2016-04-26T00:13:29Z","updated_at":"2016-04-26T00:13:29Z","html_url":"https://github.com/opencontainers/runc/pull/774#discussion_r61011863","pull_request_url":"https://api.github.com/repos/opencontainers/runc/pulls/774","_links":{"self":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/comments/61011863"},"html":{"href":"https://github.com/opencontainers/runc/pull/774#discussion_r61011863"},"pull_request":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/774"}}},"pull_request":{"url":"https://api.github.com/repos/opencontainers/runc/pulls/774","id":67606892,"html_url":"https://github.com/opencontainers/runc/pull/774","diff_url":"https://github.com/opencontainers/runc/pull/774.diff","patch_url":"https://github.com/opencontainers/runc/pull/774.patch","issue_url":"https://api.github.com/repos/opencontainers/runc/issues/774","number":774,"state":"open","locked":false,"title":"Rootless Containers","user":{"login":"cyphar","id":2888411,"avatar_url":"https://avatars.githubusercontent.com/u/2888411?v=3","gravatar_id":"","url":"https://api.github.com/users/cyphar","html_url":"https://github.com/cyphar","followers_url":"https://api.github.com/users/cyphar/followers","following_url":"https://api.github.com/users/cyphar/following{/other_user}","gists_url":"https://api.github.com/users/cyphar/gists{/gist_id}","starred_url":"https://api.github.com/users/cyphar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cyphar/subscriptions","organizations_url":"https://api.github.com/users/cyphar/orgs","repos_url":"https://api.github.com/users/cyphar/repos","events_url":"https://api.github.com/users/cyphar/events{/privacy}","received_events_url":"https://api.github.com/users/cyphar/received_events","type":"User","site_admin":false},"body":"This enables the support for the rootless container mode. There are\r\ncertain restrictions on what non-root users can do, resulting in several\r\nrunC features not being used. There are no checks in place at the moment\r\nto make this clear to users.\r\n\r\n* All cgroup operations require having CAP_SYS_ADMIN in the root user\r\nnamespace. This means that we cannot set up *any* cgroups, or join\r\ncgroups. The new cgroup namespace doesn't fix this for us either, but\r\nhopefully we can get a patch upstream to fix this.\r\n\r\n* setgroups(2) cannot be used in a non-privileged user namespace setup,\r\nso we have to hard fail if for some reason we decide that we need\r\nsetgroups(2) enabled.\r\n\r\n* We cannot map any user other than ourselves in a rootless container,\r\nwhich means that any user-related directives won't work. You can only be\r\n\"root\".\r\n\r\nIf you want to use this, you have to make sure you remove the `gid=5` entry from the `/dev/pts` mount, and only map **your own user** in the namespace.\r\n\r\nHere's `runc start` working in both `root` and `rootless` setup:\r\n![it works](https://cloud.githubusercontent.com/assets/2888411/14762626/5c7cb66c-09c2-11e6-8ae2-59a3bc56c244.png)\r\n\r\nAnd here's `runc exec` working in both `root` and `rootless` setup:\r\n![it also works](https://cloud.githubusercontent.com/assets/2888411/14762631/75724e70-09c2-11e6-80de-bf3978cc1766.png)\r\n\r\nList of things left to do:\r\n* [x] Provide a meaningful error message if the user specifies a configuration which maps more than one user (or doesn't map the effective user).\r\n* [x] Provide a meaningful error message (don't just ignore it) if the user tries to use the `user` directive to run as a different user.\r\n* [x] Provide a meaningful error message (don't just ignore it) if the user tries to specify any cgroup settings. Currently we can't provide cgroup settings (though it should be possible if the user just so happens to own the cgroup they currently reside in).\r\n* [ ] I'm not entirely sure how well a network setup will work in this case. It should also be noted that certain things like ping will not work in a container because you don't have the right capabilities in the root namespace. Which is quite annoying.\r\n* [x] `runc exec` doesn't work, and we should be able to implement it. This actually complicates the code in `nsenter.c` which checks whether the container is unprivileged. `setgroup` needs special treatment.\r\n* [x] `runc exec` doesnt' work with `root` running the exec and a rootless container (ironically). This is because we autodetect the `rootless` parameter on run, which isn't accurate. This can be fixed by storing the `rootless` flag in the `state.json`.\r\n* [x] `rootless` should be passed to the init through netlink. Currently we are doing the `rootless` check in two places and it doesn't make sense to do the check in `nsenter.c` -- we might actually have to do it with capability checks in the future.\r\n* [ ] `runc events` doesn't work because the `rootless.Manager` doesn't appear to manage the paths properly, so it can't get any data from the cgroups.\r\n\r\nTesting:\r\n* [x] Make sure that the cgroup namespace actually allows us to set cgroups. **It doesn't**.\r\n\r\nImplements #38.\r\n\r\nSigned-off-by: Aleksa Sarai <asarai@suse.de>","created_at":"2016-04-23T13:36:26Z","updated_at":"2016-04-26T00:13:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"19a7c7e2f994317d0296536710e6c8732372e881","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/opencontainers/runc/pulls/774/commits","review_comments_url":"https://api.github.com/repos/opencontainers/runc/pulls/774/comments","review_comment_url":"https://api.github.com/repos/opencontainers/runc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opencontainers/runc/issues/774/comments","statuses_url":"https://api.github.com/repos/opencontainers/runc/statuses/43e810aaac48c340218f4565d0d8a2d62b1a91e3","head":{"label":"cyphar:rootless-containers","ref":"rootless-containers","sha":"43e810aaac48c340218f4565d0d8a2d62b1a91e3","user":{"login":"cyphar","id":2888411,"avatar_url":"https://avatars.githubusercontent.com/u/2888411?v=3","gravatar_id":"","url":"https://api.github.com/users/cyphar","html_url":"https://github.com/cyphar","followers_url":"https://api.github.com/users/cyphar/followers","following_url":"https://api.github.com/users/cyphar/following{/other_user}","gists_url":"https://api.github.com/users/cyphar/gists{/gist_id}","starred_url":"https://api.github.com/users/cyphar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cyphar/subscriptions","organizations_url":"https://api.github.com/users/cyphar/orgs","repos_url":"https://api.github.com/users/cyphar/repos","events_url":"https://api.github.com/users/cyphar/events{/privacy}","received_events_url":"https://api.github.com/users/cyphar/received_events","type":"User","site_admin":false},"repo":{"id":38178794,"name":"runc","full_name":"cyphar/runc","owner":{"login":"cyphar","id":2888411,"avatar_url":"https://avatars.githubusercontent.com/u/2888411?v=3","gravatar_id":"","url":"https://api.github.com/users/cyphar","html_url":"https://github.com/cyphar","followers_url":"https://api.github.com/users/cyphar/followers","following_url":"https://api.github.com/users/cyphar/following{/other_user}","gists_url":"https://api.github.com/users/cyphar/gists{/gist_id}","starred_url":"https://api.github.com/users/cyphar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cyphar/subscriptions","organizations_url":"https://api.github.com/users/cyphar/orgs","repos_url":"https://api.github.com/users/cyphar/repos","events_url":"https://api.github.com/users/cyphar/events{/privacy}","received_events_url":"https://api.github.com/users/cyphar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cyphar/runc","description":"runc container cli tools","fork":true,"url":"https://api.github.com/repos/cyphar/runc","forks_url":"https://api.github.com/repos/cyphar/runc/forks","keys_url":"https://api.github.com/repos/cyphar/runc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cyphar/runc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cyphar/runc/teams","hooks_url":"https://api.github.com/repos/cyphar/runc/hooks","issue_events_url":"https://api.github.com/repos/cyphar/runc/issues/events{/number}","events_url":"https://api.github.com/repos/cyphar/runc/events","assignees_url":"https://api.github.com/repos/cyphar/runc/assignees{/user}","branches_url":"https://api.github.com/repos/cyphar/runc/branches{/branch}","tags_url":"https://api.github.com/repos/cyphar/runc/tags","blobs_url":"https://api.github.com/repos/cyphar/runc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cyphar/runc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cyphar/runc/git/refs{/sha}","trees_url":"https://api.github.com/repos/cyphar/runc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cyphar/runc/statuses/{sha}","languages_url":"https://api.github.com/repos/cyphar/runc/languages","stargazers_url":"https://api.github.com/repos/cyphar/runc/stargazers","contributors_url":"https://api.github.com/repos/cyphar/runc/contributors","subscribers_url":"https://api.github.com/repos/cyphar/runc/subscribers","subscription_url":"https://api.github.com/repos/cyphar/runc/subscription","commits_url":"https://api.github.com/repos/cyphar/runc/commits{/sha}","git_commits_url":"https://api.github.com/repos/cyphar/runc/git/commits{/sha}","comments_url":"https://api.github.com/repos/cyphar/runc/comments{/number}","issue_comment_url":"https://api.github.com/repos/cyphar/runc/issues/comments{/number}","contents_url":"https://api.github.com/repos/cyphar/runc/contents/{+path}","compare_url":"https://api.github.com/repos/cyphar/runc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cyphar/runc/merges","archive_url":"https://api.github.com/repos/cyphar/runc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cyphar/runc/downloads","issues_url":"https://api.github.com/repos/cyphar/runc/issues{/number}","pulls_url":"https://api.github.com/repos/cyphar/runc/pulls{/number}","milestones_url":"https://api.github.com/repos/cyphar/runc/milestones{/number}","notifications_url":"https://api.github.com/repos/cyphar/runc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cyphar/runc/labels{/name}","releases_url":"https://api.github.com/repos/cyphar/runc/releases{/id}","deployments_url":"https://api.github.com/repos/cyphar/runc/deployments","created_at":"2015-06-27T23:14:24Z","updated_at":"2016-01-21T20:41:56Z","pushed_at":"2016-04-25T16:57:35Z","git_url":"git://github.com/cyphar/runc.git","ssh_url":"git@github.com:cyphar/runc.git","clone_url":"https://github.com/cyphar/runc.git","svn_url":"https://github.com/cyphar/runc","homepage":"","size":3097,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"opencontainers:master","ref":"master","sha":"091ed0b04366054b8671e2e125f545928d0cb68b","user":{"login":"opencontainers","id":12563465,"avatar_url":"https://avatars.githubusercontent.com/u/12563465?v=3","gravatar_id":"","url":"https://api.github.com/users/opencontainers","html_url":"https://github.com/opencontainers","followers_url":"https://api.github.com/users/opencontainers/followers","following_url":"https://api.github.com/users/opencontainers/following{/other_user}","gists_url":"https://api.github.com/users/opencontainers/gists{/gist_id}","starred_url":"https://api.github.com/users/opencontainers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencontainers/subscriptions","organizations_url":"https://api.github.com/users/opencontainers/orgs","repos_url":"https://api.github.com/users/opencontainers/repos","events_url":"https://api.github.com/users/opencontainers/events{/privacy}","received_events_url":"https://api.github.com/users/opencontainers/received_events","type":"Organization","site_admin":false},"repo":{"id":36960321,"name":"runc","full_name":"opencontainers/runc","owner":{"login":"opencontainers","id":12563465,"avatar_url":"https://avatars.githubusercontent.com/u/12563465?v=3","gravatar_id":"","url":"https://api.github.com/users/opencontainers","html_url":"https://github.com/opencontainers","followers_url":"https://api.github.com/users/opencontainers/followers","following_url":"https://api.github.com/users/opencontainers/following{/other_user}","gists_url":"https://api.github.com/users/opencontainers/gists{/gist_id}","starred_url":"https://api.github.com/users/opencontainers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencontainers/subscriptions","organizations_url":"https://api.github.com/users/opencontainers/orgs","repos_url":"https://api.github.com/users/opencontainers/repos","events_url":"https://api.github.com/users/opencontainers/events{/privacy}","received_events_url":"https://api.github.com/users/opencontainers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opencontainers/runc","description":"runc container cli tools","fork":false,"url":"https://api.github.com/repos/opencontainers/runc","forks_url":"https://api.github.com/repos/opencontainers/runc/forks","keys_url":"https://api.github.com/repos/opencontainers/runc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opencontainers/runc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opencontainers/runc/teams","hooks_url":"https://api.github.com/repos/opencontainers/runc/hooks","issue_events_url":"https://api.github.com/repos/opencontainers/runc/issues/events{/number}","events_url":"https://api.github.com/repos/opencontainers/runc/events","assignees_url":"https://api.github.com/repos/opencontainers/runc/assignees{/user}","branches_url":"https://api.github.com/repos/opencontainers/runc/branches{/branch}","tags_url":"https://api.github.com/repos/opencontainers/runc/tags","blobs_url":"https://api.github.com/repos/opencontainers/runc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opencontainers/runc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opencontainers/runc/git/refs{/sha}","trees_url":"https://api.github.com/repos/opencontainers/runc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opencontainers/runc/statuses/{sha}","languages_url":"https://api.github.com/repos/opencontainers/runc/languages","stargazers_url":"https://api.github.com/repos/opencontainers/runc/stargazers","contributors_url":"https://api.github.com/repos/opencontainers/runc/contributors","subscribers_url":"https://api.github.com/repos/opencontainers/runc/subscribers","subscription_url":"https://api.github.com/repos/opencontainers/runc/subscription","commits_url":"https://api.github.com/repos/opencontainers/runc/commits{/sha}","git_commits_url":"https://api.github.com/repos/opencontainers/runc/git/commits{/sha}","comments_url":"https://api.github.com/repos/opencontainers/runc/comments{/number}","issue_comment_url":"https://api.github.com/repos/opencontainers/runc/issues/comments{/number}","contents_url":"https://api.github.com/repos/opencontainers/runc/contents/{+path}","compare_url":"https://api.github.com/repos/opencontainers/runc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opencontainers/runc/merges","archive_url":"https://api.github.com/repos/opencontainers/runc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opencontainers/runc/downloads","issues_url":"https://api.github.com/repos/opencontainers/runc/issues{/number}","pulls_url":"https://api.github.com/repos/opencontainers/runc/pulls{/number}","milestones_url":"https://api.github.com/repos/opencontainers/runc/milestones{/number}","notifications_url":"https://api.github.com/repos/opencontainers/runc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opencontainers/runc/labels{/name}","releases_url":"https://api.github.com/repos/opencontainers/runc/releases{/id}","deployments_url":"https://api.github.com/repos/opencontainers/runc/deployments","created_at":"2015-06-05T23:30:45Z","updated_at":"2016-04-25T14:47:13Z","pushed_at":"2016-04-25T23:17:34Z","git_url":"git://github.com/opencontainers/runc.git","ssh_url":"git@github.com:opencontainers/runc.git","clone_url":"https://github.com/opencontainers/runc.git","svn_url":"https://github.com/opencontainers/runc","homepage":"","size":5324,"stargazers_count":2724,"watchers_count":2724,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":342,"mirror_url":null,"open_issues_count":53,"forks":342,"open_issues":53,"watchers":2724,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/774"},"html":{"href":"https://github.com/opencontainers/runc/pull/774"},"issue":{"href":"https://api.github.com/repos/opencontainers/runc/issues/774"},"comments":{"href":"https://api.github.com/repos/opencontainers/runc/issues/774/comments"},"review_comments":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/774/comments"},"review_comment":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/774/commits"},"statuses":{"href":"https://api.github.com/repos/opencontainers/runc/statuses/43e810aaac48c340218f4565d0d8a2d62b1a91e3"}}}}