{"action":"created","comment":{"url":"https://api.github.com/repos/snapcore/snap-confine/pulls/comments/77986791","id":77986791,"diff_hunk":"@@ -0,0 +1,406 @@\n+/*\n+ * Copyright (C) 2016 Canonical Ltd\n+ *\n+ * This program is free software: you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License version 3 as\n+ * published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n+ *\n+ */\n+\n+#include \"ns-support.h\"\n+\n+#ifdef HAVE_CONFIG_H\n+#include \"config.h\"\n+#endif\n+\n+#include <errno.h>\n+#include <fcntl.h>\n+#include <sched.h>\n+#include <signal.h>\n+#include <string.h>\n+#include <sys/eventfd.h>\n+#include <sys/file.h>\n+#include <sys/mount.h>\n+#include <sys/prctl.h>\n+#include <sys/stat.h>\n+#include <sys/types.h>\n+#include <sys/types.h>\n+#include <sys/wait.h>\n+#include <unistd.h>\n+#ifdef HAVE_APPARMOR\n+#include <sys/apparmor.h>\n+#endif\t\t\t\t// ifdef HAVE_APPARMOR\n+\n+#include \"utils.h\"\n+#include \"user-support.h\"\n+#include \"mountinfo.h\"\n+#include \"cleanup-funcs.h\"\n+\n+/**\n+ * Directory where snap-confine keeps namespace files.\n+ **/\n+#define SC_NS_DIR \"/run/snapd/ns\"\n+\n+/**\n+ * Effective value of SC_NS_DIR.\n+ *\n+ * This is only altered for testing.","path":"src/ns-support.c","position":55,"original_position":55,"commit_id":"0f516485662b1af23222ed144731c91f4a4ba755","original_commit_id":"a369644e412d50d52050a028d4b31b1f3fc5fc72","user":{"login":"zyga","id":784262,"avatar_url":"https://avatars.githubusercontent.com/u/784262?v=3","gravatar_id":"","url":"https://api.github.com/users/zyga","html_url":"https://github.com/zyga","followers_url":"https://api.github.com/users/zyga/followers","following_url":"https://api.github.com/users/zyga/following{/other_user}","gists_url":"https://api.github.com/users/zyga/gists{/gist_id}","starred_url":"https://api.github.com/users/zyga/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zyga/subscriptions","organizations_url":"https://api.github.com/users/zyga/orgs","repos_url":"https://api.github.com/users/zyga/repos","events_url":"https://api.github.com/users/zyga/events{/privacy}","received_events_url":"https://api.github.com/users/zyga/received_events","type":"User","site_admin":false},"body":"Done","created_at":"2016-09-08T11:11:33Z","updated_at":"2016-09-08T11:11:33Z","html_url":"https://github.com/snapcore/snap-confine/pull/126#discussion_r77986791","pull_request_url":"https://api.github.com/repos/snapcore/snap-confine/pulls/126","_links":{"self":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/comments/77986791"},"html":{"href":"https://github.com/snapcore/snap-confine/pull/126#discussion_r77986791"},"pull_request":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/126"}}},"pull_request":{"url":"https://api.github.com/repos/snapcore/snap-confine/pulls/126","id":84113824,"html_url":"https://github.com/snapcore/snap-confine/pull/126","diff_url":"https://github.com/snapcore/snap-confine/pull/126.diff","patch_url":"https://github.com/snapcore/snap-confine/pull/126.patch","issue_url":"https://api.github.com/repos/snapcore/snap-confine/issues/126","number":126,"state":"open","locked":false,"title":"Add support module for namespace sharing","user":{"login":"zyga","id":784262,"avatar_url":"https://avatars.githubusercontent.com/u/784262?v=3","gravatar_id":"","url":"https://api.github.com/users/zyga","html_url":"https://github.com/zyga","followers_url":"https://api.github.com/users/zyga/followers","following_url":"https://api.github.com/users/zyga/following{/other_user}","gists_url":"https://api.github.com/users/zyga/gists{/gist_id}","starred_url":"https://api.github.com/users/zyga/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zyga/subscriptions","organizations_url":"https://api.github.com/users/zyga/orgs","repos_url":"https://api.github.com/users/zyga/repos","events_url":"https://api.github.com/users/zyga/events{/privacy}","received_events_url":"https://api.github.com/users/zyga/received_events","type":"User","site_admin":false},"body":"This patch adds a module that implements mount namespace sharing. It is\r\nnot yet used by snap-confine. The module implements a set of library\r\nfunctions that can perform the necessary magic.\r\n\r\nAs the topic is a bit unexpected a brief description follows.\r\n\r\nLinux namespaces can be created with the unshare(2) call. They are\r\nrepresented as files in the nsfs filesystem under /proc/$pid/ns/. The\r\nmount namespace is represented as /proc/$pid/ns/mnt. An open file\r\ndescriptor to a file like that can be used along with setns(2) to move a\r\nthread to a different namespace.\r\n\r\nWhile namespaces are normally bound to the lifetime of a given process\r\nthey can be preserved by bind-mounting the appropriate namespace file to\r\nanother location. This feature serves as the basis for the namespace\r\nsharing feature.\r\n\r\nThe mount namespace is a little bit special as it requires some\r\nadditional things to be in place before the bind mount can happen. All\r\nviolations of the rules listed below results in mount failing with\r\nEINVAL.\r\n\r\nIn order to preserve the mount namespace the calling process must be in\r\na different mount namespace (snap-confine just uses the original namespace in\r\nwhich it executes). This can be achieved by forking a child process that\r\ncan see its parent mount namespace file in /proc/$ppid/ns/mnt and having\r\nthe parent process move to a new namespace by calling unshare(). The\r\ndestination of the bind mount must be on a filesystem that is mounted\r\nwithout any peers (in the sense of shared subtrees). This can be checked\r\nby inspecting and parsing the /proc/self/mountinfo file. The new module\r\nincludes support function that bind mounts the target directory over\r\nitself and the converts it to a private mount.\r\n\r\nActual mount namespaces are kept in /run/snapd/ns (this is also the\r\ndirectory that gets converted to a private mount). The actual namespaces\r\nare put in \"groups\" with names identical to the snap name. In practice\r\nthe preserved namespaces are in /run/snapd/ns/$SNAP_NAME.mnt\r\n\r\nIn order to make everything race-free the library uses locking based on\r\nflock(2). There are two lock files. One global, required to make\r\n/run/snapd/ns a private mount, and one local, required to manipulate a\r\nparticular mount namespace. The locks are /run/snapd/ns/.lock and\r\n/run/snaps/ns/$SNAP_NAME.lock respectively.\r\n\r\nEverything is coded defensively, terminating the process in case\r\nsomething bad happens. The child process of snap-confine is using\r\nprctl() to ensure it gets killed when the parent process dies for any\r\nreason.\r\n\r\nOne notable thing that is *not* present in this patch is the adjusted\r\napparmor profile for snap-confine and for its child process (it switches\r\nhats to a new profile for added paranoia and security). It will be\r\npresented along with a, hopefully small, patch that enables namespace\r\nsharing in practice.\r\n\r\nSigned-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>","created_at":"2016-09-06T12:34:52Z","updated_at":"2016-09-08T11:11:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"566c8eda55a1709392955c4788792d8d169cc70b","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/snapcore/snap-confine/pulls/126/commits","review_comments_url":"https://api.github.com/repos/snapcore/snap-confine/pulls/126/comments","review_comment_url":"https://api.github.com/repos/snapcore/snap-confine/pulls/comments{/number}","comments_url":"https://api.github.com/repos/snapcore/snap-confine/issues/126/comments","statuses_url":"https://api.github.com/repos/snapcore/snap-confine/statuses/0f516485662b1af23222ed144731c91f4a4ba755","head":{"label":"snapcore:ns-sharing","ref":"ns-sharing","sha":"0f516485662b1af23222ed144731c91f4a4ba755","user":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"repo":{"id":59485230,"name":"snap-confine","full_name":"snapcore/snap-confine","owner":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/snapcore/snap-confine","description":"Runner for snaps","fork":false,"url":"https://api.github.com/repos/snapcore/snap-confine","forks_url":"https://api.github.com/repos/snapcore/snap-confine/forks","keys_url":"https://api.github.com/repos/snapcore/snap-confine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/snapcore/snap-confine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/snapcore/snap-confine/teams","hooks_url":"https://api.github.com/repos/snapcore/snap-confine/hooks","issue_events_url":"https://api.github.com/repos/snapcore/snap-confine/issues/events{/number}","events_url":"https://api.github.com/repos/snapcore/snap-confine/events","assignees_url":"https://api.github.com/repos/snapcore/snap-confine/assignees{/user}","branches_url":"https://api.github.com/repos/snapcore/snap-confine/branches{/branch}","tags_url":"https://api.github.com/repos/snapcore/snap-confine/tags","blobs_url":"https://api.github.com/repos/snapcore/snap-confine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/snapcore/snap-confine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/snapcore/snap-confine/git/refs{/sha}","trees_url":"https://api.github.com/repos/snapcore/snap-confine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/snapcore/snap-confine/statuses/{sha}","languages_url":"https://api.github.com/repos/snapcore/snap-confine/languages","stargazers_url":"https://api.github.com/repos/snapcore/snap-confine/stargazers","contributors_url":"https://api.github.com/repos/snapcore/snap-confine/contributors","subscribers_url":"https://api.github.com/repos/snapcore/snap-confine/subscribers","subscription_url":"https://api.github.com/repos/snapcore/snap-confine/subscription","commits_url":"https://api.github.com/repos/snapcore/snap-confine/commits{/sha}","git_commits_url":"https://api.github.com/repos/snapcore/snap-confine/git/commits{/sha}","comments_url":"https://api.github.com/repos/snapcore/snap-confine/comments{/number}","issue_comment_url":"https://api.github.com/repos/snapcore/snap-confine/issues/comments{/number}","contents_url":"https://api.github.com/repos/snapcore/snap-confine/contents/{+path}","compare_url":"https://api.github.com/repos/snapcore/snap-confine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/snapcore/snap-confine/merges","archive_url":"https://api.github.com/repos/snapcore/snap-confine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/snapcore/snap-confine/downloads","issues_url":"https://api.github.com/repos/snapcore/snap-confine/issues{/number}","pulls_url":"https://api.github.com/repos/snapcore/snap-confine/pulls{/number}","milestones_url":"https://api.github.com/repos/snapcore/snap-confine/milestones{/number}","notifications_url":"https://api.github.com/repos/snapcore/snap-confine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/snapcore/snap-confine/labels{/name}","releases_url":"https://api.github.com/repos/snapcore/snap-confine/releases{/id}","deployments_url":"https://api.github.com/repos/snapcore/snap-confine/deployments","created_at":"2016-05-23T13:29:44Z","updated_at":"2016-09-02T06:06:15Z","pushed_at":"2016-09-08T11:10:54Z","git_url":"git://github.com/snapcore/snap-confine.git","ssh_url":"git@github.com:snapcore/snap-confine.git","clone_url":"https://github.com/snapcore/snap-confine.git","svn_url":"https://github.com/snapcore/snap-confine","homepage":"","size":1190,"stargazers_count":7,"watchers_count":7,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15,"mirror_url":null,"open_issues_count":4,"forks":15,"open_issues":4,"watchers":7,"default_branch":"master"}},"base":{"label":"snapcore:master","ref":"master","sha":"bfdfd8ee8ec790d80c8fbb6166acd2a21d515860","user":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"repo":{"id":59485230,"name":"snap-confine","full_name":"snapcore/snap-confine","owner":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/snapcore/snap-confine","description":"Runner for snaps","fork":false,"url":"https://api.github.com/repos/snapcore/snap-confine","forks_url":"https://api.github.com/repos/snapcore/snap-confine/forks","keys_url":"https://api.github.com/repos/snapcore/snap-confine/keys{/key_id}","collaborators_url":"https://api.github.com/repos/snapcore/snap-confine/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/snapcore/snap-confine/teams","hooks_url":"https://api.github.com/repos/snapcore/snap-confine/hooks","issue_events_url":"https://api.github.com/repos/snapcore/snap-confine/issues/events{/number}","events_url":"https://api.github.com/repos/snapcore/snap-confine/events","assignees_url":"https://api.github.com/repos/snapcore/snap-confine/assignees{/user}","branches_url":"https://api.github.com/repos/snapcore/snap-confine/branches{/branch}","tags_url":"https://api.github.com/repos/snapcore/snap-confine/tags","blobs_url":"https://api.github.com/repos/snapcore/snap-confine/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/snapcore/snap-confine/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/snapcore/snap-confine/git/refs{/sha}","trees_url":"https://api.github.com/repos/snapcore/snap-confine/git/trees{/sha}","statuses_url":"https://api.github.com/repos/snapcore/snap-confine/statuses/{sha}","languages_url":"https://api.github.com/repos/snapcore/snap-confine/languages","stargazers_url":"https://api.github.com/repos/snapcore/snap-confine/stargazers","contributors_url":"https://api.github.com/repos/snapcore/snap-confine/contributors","subscribers_url":"https://api.github.com/repos/snapcore/snap-confine/subscribers","subscription_url":"https://api.github.com/repos/snapcore/snap-confine/subscription","commits_url":"https://api.github.com/repos/snapcore/snap-confine/commits{/sha}","git_commits_url":"https://api.github.com/repos/snapcore/snap-confine/git/commits{/sha}","comments_url":"https://api.github.com/repos/snapcore/snap-confine/comments{/number}","issue_comment_url":"https://api.github.com/repos/snapcore/snap-confine/issues/comments{/number}","contents_url":"https://api.github.com/repos/snapcore/snap-confine/contents/{+path}","compare_url":"https://api.github.com/repos/snapcore/snap-confine/compare/{base}...{head}","merges_url":"https://api.github.com/repos/snapcore/snap-confine/merges","archive_url":"https://api.github.com/repos/snapcore/snap-confine/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/snapcore/snap-confine/downloads","issues_url":"https://api.github.com/repos/snapcore/snap-confine/issues{/number}","pulls_url":"https://api.github.com/repos/snapcore/snap-confine/pulls{/number}","milestones_url":"https://api.github.com/repos/snapcore/snap-confine/milestones{/number}","notifications_url":"https://api.github.com/repos/snapcore/snap-confine/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/snapcore/snap-confine/labels{/name}","releases_url":"https://api.github.com/repos/snapcore/snap-confine/releases{/id}","deployments_url":"https://api.github.com/repos/snapcore/snap-confine/deployments","created_at":"2016-05-23T13:29:44Z","updated_at":"2016-09-02T06:06:15Z","pushed_at":"2016-09-08T11:10:54Z","git_url":"git://github.com/snapcore/snap-confine.git","ssh_url":"git@github.com:snapcore/snap-confine.git","clone_url":"https://github.com/snapcore/snap-confine.git","svn_url":"https://github.com/snapcore/snap-confine","homepage":"","size":1190,"stargazers_count":7,"watchers_count":7,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15,"mirror_url":null,"open_issues_count":4,"forks":15,"open_issues":4,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/126"},"html":{"href":"https://github.com/snapcore/snap-confine/pull/126"},"issue":{"href":"https://api.github.com/repos/snapcore/snap-confine/issues/126"},"comments":{"href":"https://api.github.com/repos/snapcore/snap-confine/issues/126/comments"},"review_comments":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/126/comments"},"review_comment":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/snapcore/snap-confine/pulls/126/commits"},"statuses":{"href":"https://api.github.com/repos/snapcore/snap-confine/statuses/0f516485662b1af23222ed144731c91f4a4ba755"}}}}
{"actor":{"display_login":"zyga"}}