Author: jamie
Date: Fri Jul  6 18:50:22 2018
New Revision: 336038
URL: https://svnweb.freebsd.org/changeset/base/336038

Log:
  Change prison_add_vfs() to the more generic prison_add_allow(), which
  can add any dynamic allow.* or allow.*.* parameter.  Also keep
  prison_add_vfs() as a wrapper.
  
  Differential Revision:        D16146

Modified:
  head/sys/kern/kern_jail.c
  head/sys/sys/jail.h

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c   Fri Jul  6 17:39:48 2018        (r336037)
+++ head/sys/kern/kern_jail.c   Fri Jul  6 18:50:22 2018        (r336038)
@@ -3760,37 +3760,43 @@ SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLA
     "B", "Jail may mount/unmount jail-friendly file systems in general");
 
 /*
- * The VFS system will register jail-aware filesystems here.  They each get
- * a parameter allow.mount.xxxfs and a flag to check when a jailed user
- * attempts to mount.
+ * Add a dynamic parameter allow.<name>, or allow.<prefix>.<name>.  Return
+ * its associated bit in the pr_allow bitmask, or zero if the parameter was
+ * not created.
  */
-void
-prison_add_vfs(struct vfsconf *vfsp)
+unsigned
+prison_add_allow(const char *prefix, const char *name, const char 
*prefix_descr,
+    const char *descr)
 {
-       char *allow_name, *allow_noname, *mount_allowed;
        struct bool_flags *bf;
+       struct sysctl_oid *parent;
+       char *allow_name, *allow_noname, *allowed;
 #ifndef NO_SYSCTL_DESCR
-       char *descr;
+       char *descr_deprecated;
 #endif
        unsigned allow_flag;
 
-       if (asprintf(&allow_name, M_PRISON, "allow.mount.%s", vfsp->vfc_name) <
-           0 || asprintf(&allow_noname, M_PRISON, "allow.mount.no%s",
-           vfsp->vfc_name) < 0) {
+       if (prefix
+           ? asprintf(&allow_name, M_PRISON, "allow.%s.%s", prefix, name)
+               < 0 ||
+             asprintf(&allow_noname, M_PRISON, "allow.%s.no%s", prefix, name)
+               < 0
+           : asprintf(&allow_name, M_PRISON, "allow.%s", name) < 0 ||
+             asprintf(&allow_noname, M_PRISON, "allow.no%s", name) < 0) {
                free(allow_name, M_PRISON);
-               return;
+               return 0;
        }
 
        /*
-        * See if this parameter has already beed added, i.e. if the filesystem
-        * was previously loaded/unloaded.
+        * See if this parameter has already beed added, i.e. a module was
+        * previously loaded/unloaded.
         */
        mtx_lock(&prison0.pr_mtx);
        for (bf = pr_flag_allow;
             bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
             bf++) {
                if (strcmp(bf->name, allow_name) == 0) {
-                       vfsp->vfc_prison_flag = bf->flag;
+                       allow_flag = bf->flag;
                        goto no_add;
                }
        }
@@ -3798,7 +3804,7 @@ prison_add_vfs(struct vfsconf *vfsp)
        /*
         * Find a free bit in prison0's pr_allow, failing if there are none
         * (which shouldn't happen as long as we keep track of how many
-        * filesystems are jail-aware).
+        * potential dynamic flags exist).
         */
        for (allow_flag = 1;; allow_flag <<= 1) {
                if (allow_flag == 0)
@@ -3815,52 +3821,73 @@ prison_add_vfs(struct vfsconf *vfsp)
        for (bf = pr_flag_allow; bf->flag != 0; bf++)
                if (bf == pr_flag_allow + nitems(pr_flag_allow)) {
                        /* This should never happen, but is not fatal. */
+                       allow_flag = 0;
                        goto no_add;
                }
        prison0.pr_allow |= allow_flag;
        bf->name = allow_name;
        bf->noname = allow_noname;
        bf->flag = allow_flag;
-       vfsp->vfc_prison_flag = allow_flag;
        mtx_unlock(&prison0.pr_mtx);
 
        /*
         * Create sysctls for the paramter, and the back-compat global
         * permission.
         */
-#ifndef NO_SYSCTL_DESCR
-       (void)asprintf(&descr, M_TEMP, "Jail may mount the %s file system",
-           vfsp->vfc_name);
-#endif
-       (void)SYSCTL_ADD_PROC(NULL,
-           SYSCTL_CHILDREN(&sysctl___security_jail_param_allow_mount),
-           OID_AUTO, vfsp->vfc_name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+       parent = prefix
+           ? SYSCTL_ADD_NODE(NULL,
+                 SYSCTL_CHILDREN(&sysctl___security_jail_param_allow),
+                 OID_AUTO, prefix, 0, 0, prefix_descr)
+           : &sysctl___security_jail_param_allow;
+       (void)SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(parent), OID_AUTO,
+           name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
            NULL, 0, sysctl_jail_param, "B", descr);
+       if ((prefix
+            ? asprintf(&allowed, M_TEMP, "%s_%s_allowed", prefix, name)
+            : asprintf(&allowed, M_TEMP, "%s_allowed", name)) >= 0) {
 #ifndef NO_SYSCTL_DESCR
-       free(descr, M_TEMP);
+               (void)asprintf(&descr_deprecated, M_TEMP, "%s (deprecated)",
+                   descr);
 #endif
-       if (asprintf(&mount_allowed, M_TEMP, "mount_%s_allowed",
-               vfsp->vfc_name) >= 0) {
-#ifndef NO_SYSCTL_DESCR
-               (void)asprintf(&descr, M_TEMP,
-                 "Processes in jail can mount the %s file system (deprecated)",
-                 vfsp->vfc_name);
-#endif
                (void)SYSCTL_ADD_PROC(NULL,
-                   SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO,
-                   mount_allowed, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-                   NULL, allow_flag, sysctl_jail_default_allow, "I", descr);
+                   SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO, allowed,
+                   CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, allow_flag,
+                   sysctl_jail_default_allow, "I", descr_deprecated);
 #ifndef NO_SYSCTL_DESCR
-               free(descr, M_TEMP);
+               free(descr_deprecated, M_TEMP);
 #endif
-               free(mount_allowed, M_TEMP);
+               free(allowed, M_TEMP);
        }
-       return;
+       return allow_flag;
 
  no_add:
        mtx_unlock(&prison0.pr_mtx);
        free(allow_name, M_PRISON);
        free(allow_noname, M_PRISON);
+       return allow_flag;
+}
+
+/*
+ * The VFS system will register jail-aware filesystems here.  They each get
+ * a parameter allow.mount.xxxfs and a flag to check when a jailed user
+ * attempts to mount.
+ */
+void
+prison_add_vfs(struct vfsconf *vfsp)
+{
+#ifdef NO_SYSCTL_DESCR
+
+       vfsp->vfc_prison_flag = prison_add_allow("mount", vfsp->vfc_name,
+           NULL, NULL);
+#else
+       char *descr;
+
+       (void)asprintf(&descr, M_TEMP, "Jail may mount the %s file system",
+           vfsp->vfc_name);
+       vfsp->vfc_prison_flag = prison_add_allow("mount", vfsp->vfc_name,
+           NULL, descr);
+       free(descr, M_TEMP);
+#endif
 }
 
 #ifdef RACCT

Modified: head/sys/sys/jail.h
==============================================================================
--- head/sys/sys/jail.h Fri Jul  6 17:39:48 2018        (r336037)
+++ head/sys/sys/jail.h Fri Jul  6 18:50:22 2018        (r336038)
@@ -409,6 +409,8 @@ int prison_if(struct ucred *cred, struct sockaddr *sa)
 char *prison_name(struct prison *, struct prison *);
 int prison_priv_check(struct ucred *cred, int priv);
 int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
+unsigned prison_add_allow(const char *prefix, const char *name,
+    const char *prefix_descr, const char *descr);
 void prison_add_vfs(struct vfsconf *vfsp);
 void prison_racct_foreach(void (*callback)(struct racct *racct,
     void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to