diff options
author | sobomax <sobomax@FreeBSD.org> | 2017-05-14 10:48:47 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2017-05-14 10:48:47 +0000 |
commit | 68a5ef79c2d4023b803657598a7213adce38eac1 (patch) | |
tree | a2a6e3e6b1627b4705ba20abfd93199329aa0c58 /sbin/mksnap_ffs | |
parent | d0a85a93fdbb820cc060cc3b2664e1567983f203 (diff) | |
download | FreeBSD-src-68a5ef79c2d4023b803657598a7213adce38eac1.zip FreeBSD-src-68a5ef79c2d4023b803657598a7213adce38eac1.tar.gz |
MFC r316718, r316738: make mksnap_ffs functional in the chroot'ed environment.
Diffstat (limited to 'sbin/mksnap_ffs')
-rw-r--r-- | sbin/mksnap_ffs/mksnap_ffs.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/sbin/mksnap_ffs/mksnap_ffs.c b/sbin/mksnap_ffs/mksnap_ffs.c index 7dcf5c2..db49fdb 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.c +++ b/sbin/mksnap_ffs/mksnap_ffs.c @@ -58,6 +58,33 @@ usage(void) errx(EX_USAGE, "usage: mksnap_ffs snapshot_name"); } +static int +isdir(const char *path, struct stat *stbufp) +{ + + if (stat(path, stbufp) < 0) + return (-1); + if (!S_ISDIR(stbufp->st_mode)) + return (0); + return (1); +} + +static int +issamefs(const char *path, struct statfs *stfsp) +{ + struct statfs stfsbuf; + struct stat stbuf; + + if (isdir(path, &stbuf) != 1) + return (-1); + if (statfs(path, &stfsbuf) < 0) + return (-1); + if ((stfsbuf.f_fsid.val[0] != stfsp->f_fsid.val[0]) || + (stfsbuf.f_fsid.val[1] != stfsp->f_fsid.val[1])) + return (0); + return (1); +} + int main(int argc, char **argv) { @@ -96,16 +123,33 @@ main(int argc, char **argv) } if (statfs(path, &stfsbuf) < 0) err(1, "%s", path); - if (stat(path, &stbuf) < 0) + switch (isdir(path, &stbuf)) { + case -1: err(1, "%s", path); - if (!S_ISDIR(stbuf.st_mode)) + case 0: errx(1, "%s: Not a directory", path); + default: + break; + } if (access(path, W_OK) < 0) err(1, "Lack write permission in %s", path); if ((stbuf.st_mode & S_ISTXT) && stbuf.st_uid != getuid()) errx(1, "Lack write permission in %s: Sticky bit set", path); /* + * Work around an issue when mksnap_ffs is started in chroot'ed + * environment and f_mntonname contains absolute path within + * real root. + */ + for (cp = stfsbuf.f_mntonname; issamefs(cp, &stfsbuf) != 1; + cp = strchrnul(cp + 1, '/')) { + if (cp[0] == '\0') + errx(1, "%s: Not a mount point", stfsbuf.f_mntonname); + } + if (cp != stfsbuf.f_mntonname) + strlcpy(stfsbuf.f_mntonname, cp, sizeof(stfsbuf.f_mntonname)); + + /* * Having verified access to the directory in which the * snapshot is to be built, proceed with creating it. */ |