Download raw body.
[patch] mount_mfs allow setting permissions manually
On Sun, Jul 20, 2025 at 12:59:09PM +0100, Stuart Henderson wrote:
> On 2025/07/20 04:52, Crystal Kolipe wrote:
> > Do we also need to clarify in the man page what happens if both -p and -P are
> > used at the same time? In that case, -p is ignored and the permissions from
> > the directory specified with -P are used.
> >
> > I'm wondering if that is even the desired behaviour, maybe -p should always
> > override even when -P is specified. But if nobody has an opinion on this
> > I'm OK with the current proposal.
>
> fwiw, I think I would expect -p to be used "over the top" of -P's
> permissions if both flags are specified.
This version should address that. Now if both -p and -P are specified on the
command line, the permissions of '.' are set to whatever was specified as the
argument to -p.
I'm assuming that's what you meant, although "over the top" could also be
interpreted as 'a logical AND of both the permissions gained from -P and those
specified with -p', (which could in itself could be considered an over the top
suggestion in another sense, thereby causing an infinite mental loop :-) ).
The chmod of '.' is not expected to fail, so we only print a warning if it
does, and continue with the inherited permissions. Should this be a hard
error?
--- newfs.c.orig Mon Apr 7 04:25:02 2025
+++ newfs.c Mon Jul 21 08:15:41 2025
@@ -147,7 +147,7 @@
static void waitformount(char *, pid_t);
static int do_exec(const char *, const char *, char *const[]);
static int isdir(const char *);
-static void copy(char *, char *);
+static void copy(char *, char *, mode_t);
static int gettmpmnt(char *, size_t);
#endif
@@ -179,6 +179,7 @@
#ifdef MFS
char mountfromname[BUFSIZ];
char *pop = NULL, node[PATH_MAX];
+ char *ep;
pid_t pid;
struct stat mountpoint;
#endif
@@ -203,7 +204,7 @@
fatal("insane maxpartitions value %d", maxpartitions);
opstring = mfs ?
- "O:P:T:b:c:e:f:i:m:o:s:" :
+ "O:P:T:b:c:e:f:i:m:o:p:s:" :
"NO:S:T:b:c:e:f:g:h:i:m:o:qs:t:";
while ((ch = getopt(argc, argv, opstring)) != -1) {
switch (ch) {
@@ -286,6 +287,19 @@
optarg);
}
break;
+ case 'p':
+ errno = 0;
+ mfsmode = strtoul(optarg, &ep, 8);
+ if (optarg[0] == '\0' || *ep != '\0')
+ fatal("invalid mode: not a number");
+ if (errno == ERANGE)
+ fatal("invalid mode: out of range");
+ if ((mfsmode & ALLPERMS) != mfsmode)
+ fatal("unrecognised permission bits");
+ if (mfsmode == 0)
+ warnx("invalid mode, will inherit "
+ "mount point permissions");
+ break;
case 'q':
quiet = 1;
break;
@@ -506,7 +520,8 @@
err(ECANCELED, "stat %s", node);
mfsuid = mountpoint.st_uid;
mfsgid = mountpoint.st_gid;
- mfsmode = mountpoint.st_mode & ALLPERMS;
+ if (mfsmode == 0)
+ mfsmode = mountpoint.st_mode & ALLPERMS;
}
#endif
@@ -543,7 +558,7 @@
default:
if (pop != NULL) {
waitformount(tmpnode, pid);
- copy(pop, tmpnode);
+ copy(pop, tmpnode, mfsmode);
unmount(tmpnode, 0);
rmdir(tmpnode);
}
@@ -754,13 +769,18 @@
}
static void
-copy(char *src, char *dst)
+copy(char *src, char *dst, mode_t mfsmode)
{
int ret, dir, created = 0;
+ int fd;
struct ufs_args mount_args;
char mountpoint[MNAMELEN];
char *const argv[] = { "pax", "-rw", "-pe", ".", dst, NULL } ;
+ if ((fd = open(dst, O_RDONLY)) == -1) {
+ err(1, "failed opening %s", dst);
+ }
+
dir = isdir(src);
if (dir)
strlcpy(mountpoint, src, sizeof(mountpoint));
@@ -788,6 +808,10 @@
warn("unmount %s", dst);
errx(1, "copy %s to %s failed", mountpoint, dst);
}
+ if (fchmodat(fd, ".", mfsmode, 0) == -1) {
+ warn("failed to set requested permissions");
+ }
+ close (fd);
}
static int
[patch] mount_mfs allow setting permissions manually