From Ian Kent (raven at themaw) dot net:
authorzoulasc <christos@zoulas.com>
Mon, 1 Sep 2014 08:19:43 +0000 (04:19 -0400)
committerzoulasc <christos@zoulas.com>
Mon, 1 Sep 2014 08:19:43 +0000 (04:19 -0400)
In amfs_mount() the function get_root_nfs_fh() is assumed to return an
NFSv2 handle but, if nfs_dispatcher != 2 it will write an NFSv3 handle
to the NFSv2 structure, possibly overflowing the variable.

ChangeLog
amd/amd.h
amd/autil.c
amd/map.c

index 00704b8adfb61a24cdbac24caac5680f92faf3cf..7be0fb4e0a90399889cdf07c365efe2f4d27438d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-09-01  Christos Zoulas <christos@zoulas.com>
+
+       * bug fix from raven at themaw.net to prevent writing v3 handle
+         to a v2 structure.
+
 2014-07-21  Christos Zoulas <christos@zoulas.com>
 
        * fix permission problems with access
index b9bdcf52a67550f7f02648fc9f994d88c4fe0030..f66f5b75169f4205ce48f04ce56e468dcbfac243 100644 (file)
--- a/amd/amd.h
+++ b/amd/amd.h
@@ -550,7 +550,7 @@ extern amq_sync_umnt *amqproc_sync_umnt_1_svc_async(voidp argp, struct svc_req *
 extern amq_map_info_list *amqproc_getmapinfo_1_svc(voidp argp, struct svc_req *rqstp);
 
 /* other external definitions */
-extern am_nfs_fh *get_root_nfs_fh(char *dir);
+extern am_nfs_handle_t *get_root_nfs_fh(char *dir, am_nfs_handle_t *nfh);
 extern am_node *find_ap(char *);
 extern am_node *get_ap_child(am_node *, char *);
 extern bool_t xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead);
@@ -635,6 +635,7 @@ extern int  mount_auto_node(char *, opaque_t);
 extern int  mount_automounter(int);
 extern int  mount_exported(void);
 extern void mp_to_fh(am_node *, am_nfs_fh *);
+extern void mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp);
 extern void new_ttl(am_node *);
 extern void nfs_quick_reply(am_node *mp, int error);
 extern void normalize_slash(char *);
index cc073e89f57dc88e0915135950e6392dce93d8e0..cd9514d44ef4b76079c06833d017979729a3f327 100644 (file)
@@ -524,8 +524,7 @@ amfs_mount(am_node *mp, mntfs *mf, char *opts)
 again:
   if (!(mf->mf_flags & MFF_IS_AUTOFS)) {
     nfs_args_t nfs_args;
-    am_nfs_fh *fhp;
-    am_nfs_handle_t anh;
+    am_nfs_handle_t *fhp, anh;
 #ifndef HAVE_TRANSPORT_TYPE_TLI
     u_short port;
     struct sockaddr_in sin;
@@ -534,7 +533,7 @@ again:
     /*
      * get fhandle of remote path for automount point
      */
-    fhp = get_root_nfs_fh(dir);
+    fhp = get_root_nfs_fh(dir, &anh);
     if (!fhp) {
       plog(XLOG_FATAL, "Can't find root file handle for %s", dir);
       return EINVAL;
@@ -558,7 +557,6 @@ again:
 #endif /* not HAVE_TRANSPORT_TYPE_TLI */
 
     /* setup the many fields and flags within nfs_args */
-    memmove(&anh.v2, fhp, sizeof(*fhp));
 #ifdef HAVE_TRANSPORT_TYPE_TLI
     compute_nfs_args(&nfs_args,
                     &mnt,
@@ -567,7 +565,7 @@ again:
                     NULL,      /* remote host IP addr is set below */
                     nfs_version,
                     "udp",
-                    &anh,
+                    fhp,
                     fs_hostname,
                     pid_fsname);
     /*
@@ -588,7 +586,7 @@ again:
                     &sin,
                     nfs_version,
                     "udp",
-                    &anh,
+                    fhp,
                     fs_hostname,
                     pid_fsname);
 #endif /* not HAVE_TRANSPORT_TYPE_TLI */
index d924d703c08739cac05a5f4fa2b5cb167b020dda..fce8273e4ef663a4c7a5c2b6074a342e1e916634 100644 (file)
--- a/amd/map.c
+++ b/amd/map.c
@@ -542,17 +542,16 @@ find_ap(char *dir)
  * This is used during the bootstrap to tell the kernel
  * the filehandles of the initial automount points.
  */
-am_nfs_fh *
-get_root_nfs_fh(char *dir)
+am_nfs_handle_t *
+get_root_nfs_fh(char *dir, am_nfs_handle_t *nfh)
 {
-  static am_nfs_fh nfh;
   am_node *mp = get_root_ap(dir);
   if (mp) {
     if (nfs_dispatcher == nfs_program_2)
-      mp_to_fh(mp, &nfh);
+      mp_to_fh(mp, &nfh->v2);
     else
-      mp_to_fh3(mp, &nfh);
-    return &nfh;
+      mp_to_fh3(mp, &nfh->v3);
+    return nfh;
   }
 
   /*