diff options
| author | <gerald.jelinek@sun.com> | 2008-10-07 09:35:01 -0600 |
|---|---|---|
| committer | <gerald.jelinek@sun.com> | 2008-10-07 09:35:01 -0600 |
| commit | c4a4562235be590fa8120d4e0dc367980a14112f (patch) | |
| tree | 7cab98c16f7cb50f95d0b2b4c0cfc8f9d61db1ac /usr/src/cmd/zoneadm | |
| parent | a55f711916b9f7718fabc2d1822bf5719aa6140f (diff) | |
| download | illumos-joyent-c4a4562235be590fa8120d4e0dc367980a14112f.tar.gz | |
6754405 configured zonepath root validation is too restrictive
Diffstat (limited to 'usr/src/cmd/zoneadm')
| -rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.c | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index 3ee3c3879b..12d0dd6711 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -1095,18 +1095,64 @@ validate_zonepath(char *path, int cmd_num) return (Z_ERR); } if ((res = stat(rootpath, &stbuf)) == 0) { - if (zonecfg_detached(rpath)) + struct dirent *dp; + DIR *dirp; + boolean_t empty = B_TRUE; + + if (zonecfg_detached(rpath)) { (void) fprintf(stderr, gettext("Cannot %s detached " "zone.\nUse attach or remove %s " "directory.\n"), cmd_to_str(cmd_num), rpath); - else - (void) fprintf(stderr, - gettext("Rootpath %s exists; " - "remove or move aside prior to %s.\n"), - rootpath, cmd_to_str(cmd_num)); - return (Z_ERR); + return (Z_ERR); + } + + /* Not detached, check if it really looks ok. */ + + if (!S_ISDIR(stbuf.st_mode)) { + (void) fprintf(stderr, gettext("%s is not a " + "directory.\n"), rootpath); + return (Z_ERR); + } + + if (stbuf.st_uid != 0) { + (void) fprintf(stderr, gettext("%s is not " + "owned by root.\n"), rootpath); + return (Z_ERR); + } + + if ((stbuf.st_mode & 0777) != 0755) { + (void) fprintf(stderr, gettext("%s mode is not " + "0755.\n"), rootpath); + return (Z_ERR); + } + + if ((dirp = opendir(rootpath)) == NULL) { + (void) fprintf(stderr, gettext("Could not " + "open rootpath %s\n"), rootpath); + return (Z_ERR); + } + + /* Verify that the dir is empty. */ + while ((dp = readdir(dirp)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0) + continue; + + empty = B_FALSE; + break; + } + (void) closedir(dirp); + + if (!empty) { + (void) fprintf(stderr, gettext("Rootpath %s " + "exists and contains data; remove or move " + "aside prior to %s.\n"), rootpath, + cmd_to_str(cmd_num)); + return (Z_ERR); + } + } } |
