diff options
author | wchang kim <wchang.kim@samsung.com> | 2016-12-09 16:02:55 +0900 |
---|---|---|
committer | wchang kim <wchang.kim@samsung.com> | 2016-12-12 13:13:44 +0900 |
commit | 4d75e390f11c074529e93b4497c2fdc1320a2c4a (patch) | |
tree | aa292f1130362b5cadfd366cbce7156c958e08e7 | |
parent | 1c4f78e6bd97a69d805f452ccb8aa0c38cb76cd3 (diff) | |
download | system-plugin-4d75e390f11c074529e93b4497c2fdc1320a2c4a.tar.gz system-plugin-4d75e390f11c074529e93b4497c2fdc1320a2c4a.tar.bz2 system-plugin-4d75e390f11c074529e93b4497c2fdc1320a2c4a.zip |
Add the directory for system session and user session to share.submit/tizen_3.0/20161212.042035
Making the directory of /run/user_ext/<uid>.
Mounting tmpfs to it with smackfstransmute System::Run.
Unmounting directories which systemd_user_helper made when service is
stopped.
Change-Id: Ia749ba8ec291018c29216c65a0d47ee7ab385dbc
Signed-off-by: Woochang Kim <wchang.kim@samsung.com>
-rw-r--r-- | packaging/system-plugin.spec | 5 | ||||
-rw-r--r-- | packaging/systemd-user-helper.manifest | 3 | ||||
-rw-r--r-- | src/systemd-user-helper/systemd-user-helper.c | 176 |
3 files changed, 177 insertions, 7 deletions
diff --git a/packaging/system-plugin.spec b/packaging/system-plugin.spec index fe80dd9..ec8a348 100644 --- a/packaging/system-plugin.spec +++ b/packaging/system-plugin.spec @@ -320,9 +320,12 @@ mv %{_sysconfdir}/fstab_lazymnt %{_sysconfdir}/fstab %posttrans -n systemd-user-helper cp -a /usr/lib/systemd/system/user\@.service /usr/lib/systemd/system/__user@.service /usr/bin/sed -i -e 's/Type=\(.*\)/Type=forking/' /usr/lib/systemd/system/user\@.service -/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper %i/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper start %i/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/ExecStart=\(.*\)/ a ExecStop=\/usr\/bin\/systemd_user_helper stop %i' /usr/lib/systemd/system/user\@.service /usr/bin/sed -i -e '/PIDFile=\(.*\)/d' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/XDG_RUNTIME_DIR/ a Environment=XDG_RUNTIME_EXT_DIR=/run/user_ext/%i' /usr/lib/systemd/system/user\@.service echo 'PIDFile=/run/user/%i/.systemd.pid' >> /usr/lib/systemd/system/user\@.service +echo "d /run/user_ext 0755 root root -" >> /usr/lib/tmpfiles.d/systemd.conf %files profile_ivi %{_prefix}/lib/udev/rules.d/99-usb-ethernet.rules diff --git a/packaging/systemd-user-helper.manifest b/packaging/systemd-user-helper.manifest index 2a0cec5..bcde152 100644 --- a/packaging/systemd-user-helper.manifest +++ b/packaging/systemd-user-helper.manifest @@ -2,4 +2,7 @@ <request> <domain name="_"/> </request> + <assign> + <filesystem path="/usr/bin/systemd_user_helper" label="System::Privileged" exec_label="System::Privileged" /> + </assign> </manifest> diff --git a/src/systemd-user-helper/systemd-user-helper.c b/src/systemd-user-helper/systemd-user-helper.c index 6ffe977..a8145fa 100644 --- a/src/systemd-user-helper/systemd-user-helper.c +++ b/src/systemd-user-helper/systemd-user-helper.c @@ -29,6 +29,10 @@ #include <tzplatform_config.h> +#include <sys/types.h> +#include <grp.h> +#include <string.h> + #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) #define PIDFILE_PATH ".systemd.pid" @@ -49,6 +53,10 @@ } \ } while (0); +#define MOUNT_SIZE "10000k" +#define MAX_GRP_BUF_SIZE (1024 * 4) +#define GRP_NAME_SYSTEM_SHARE "system_share" + static void *container_handle = NULL; static const char *systemd_arg[] = { @@ -57,9 +65,117 @@ static const char *systemd_arg[] = { NULL }; +int mac_smack_use(void) { + static int cached_use = -1; + + if (cached_use < 0) + cached_use = access("/sys/fs/smackfs/", F_OK) >= 0; + + return cached_use; +} + +static int mount_user_ext(char *username) +{ + char *mount_point = NULL; + char *mount_option = NULL; + uid_t mnt_uid; + gid_t mnt_gid; + struct group *p_grp = NULL, grp_buf; + char buf[MAX_GRP_BUF_SIZE]; + int r; + + mnt_uid = atoi(username); + if(mnt_uid <= 0) + return -1; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + + (void) mkdir(mount_point, 0750); + + r = getgrnam_r(GRP_NAME_SYSTEM_SHARE, &grp_buf, buf, sizeof(buf), &p_grp); + if( r == 0 && p_grp != NULL) + { + mnt_gid = p_grp->gr_gid; + } + else + { + free(mount_point); + return -2; + } + + if (mac_smack_use()) + r = asprintf(&mount_option, "mode=0750,smackfstransmute=System::Run,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + else + r = asprintf(&mount_option, "mode=0750,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + + if (r < 0) { + fprintf(stderr, "Failed to set mount option for user_ext\n"); + free(mount_point); + return r; + } + + r = mount("tmpfs", mount_point, "tmpfs", MS_NODEV|MS_NOSUID|MS_NOEXEC, mount_option); + free(mount_point); + free(mount_option); + + if (r < 0) { + fprintf(stderr, "Failed to mount user_ext\n"); + return r; + } + return 0; +} + +static int umount_user_ext(char *username) +{ + int r; + char *mount_point = NULL; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + r = umount2(mount_point, MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Failed to umount user_ext\n"); + free(mount_point); + return r; + } + r = rmdir(mount_point); + if (r < 0) { + fprintf(stderr, "Failed to rmdir user_ext\n"); + free(mount_point); + return r; + } + free(mount_point); + return 0; +} + +static int stop_process(char *username) +{ + int r; + + (void)umount_user_ext(username); + r = umount2(tzplatform_getenv(TZ_USER_CONTENT), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount user content\n"); + } + + r = umount2(tzplatform_getenv(TZ_USER_APP), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount application content\n"); + } + return 0; +} + static int normal_user_preprocess(char *username) { int r; + r = unshare(CLONE_NEWNS); if (r < 0) { fprintf(stderr, "unshare failed\n"); @@ -198,6 +314,30 @@ static int make_pid_file(int pid, char* user_id) return r; } +static int change_smack_for_user_session() +{ + FILE *fp; + int r = 0; + + fp = fopen("/proc/self/attr/current", "w"); + + if(fp == NULL) + { + r = -errno; + return r; + } + r = fputs("User", fp); + if(r == EOF) + { + fclose(fp); + r = -errno; + return r; + } + fclose(fp); + + return 0; +} + int run_child(int argc, const char *argv[], char* user_id) { pid_t pid; @@ -230,14 +370,38 @@ int main(int argc, char *argv[]) { int r = 0; int support_container = 0; + char *operation; + char *username; - if (argc < 2) { + if (argc < 3) { fprintf(stderr, "require user argument\n"); return -1; } + operation = argv[1]; + username = argv[2]; + + if (strcmp(operation,"stop") == 0) { + return stop_process(username); + } else if (strcmp(operation, "start") == 0) { + } else { + fprintf(stderr, "option is invalid(%s)\n", operation); + return -2; + } + + r = mount_user_ext(username); + if (r < 0) { + fprintf(stderr, "mount user_ext failed\n"); + return r; + } + r = change_smack_for_user_session(); + if(r != 0) + { + fprintf(stderr, "failed to change smack\n"); + return r; + } /* pre-processing */ - r = normal_user_preprocess(argv[1]); + r = normal_user_preprocess(username); if (r < 0) { fprintf(stderr, "normal user preprocess failed\n"); return r; @@ -246,14 +410,14 @@ int main(int argc, char *argv[]) /* If container supports below funcs, below line should be enabled. */ support_container = (access(CONTAINER_LIB, F_OK) == 0) ? 1 : 0; if (support_container) { - r = container_preprocess(argv[1]); + r = container_preprocess(username); if (r < 0) { fprintf(stderr, "container preprocess failed\n"); return r; } } - r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, argv[1]); + r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, username); if (r < 0) { fprintf(stderr, "systemd user execution failed\n"); return r; @@ -265,14 +429,14 @@ int main(int argc, char *argv[]) wait_condition(); /* post-processing */ - r = normal_user_postprocess(argv[1]); + r = normal_user_postprocess(username); if (r < 0) { fprintf(stderr, "normal user postprocess failed\n"); return r; } if (support_container) { - r = container_postprocess(argv[1]); + r = container_postprocess(username); if (r < 0) { fprintf(stderr, "container postprocess failed\n"); return r; |