Page MenuHomeFreeBSD

D25077.id72486.diff
No OneTemporary

D25077.id72486.diff

Index: sys/fs/tmpfs/tmpfs.h
===================================================================
--- sys/fs/tmpfs/tmpfs.h
+++ sys/fs/tmpfs/tmpfs.h
@@ -37,6 +37,7 @@
#ifndef _FS_TMPFS_TMPFS_H_
#define _FS_TMPFS_TMPFS_H_
+#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/tree.h>
@@ -393,12 +394,12 @@
* This structure maps a file identifier to a tmpfs node. Used by the
* NFS code.
*/
-struct tmpfs_fid {
- uint16_t tf_len;
- uint16_t tf_pad;
- ino_t tf_id;
- unsigned long tf_gen;
+struct tmpfs_fid_data {
+ ino_t tfd_id;
+ unsigned long tfd_gen;
};
+_Static_assert(sizeof(struct tmpfs_fid_data) <= MAXFIDSZ,
+ "(struct tmpfs_fid_data) is larger than (struct fid).fid_data");
struct tmpfs_dir_cursor {
struct tmpfs_dirent *tdc_current;
Index: sys/fs/tmpfs/tmpfs_vfsops.c
===================================================================
--- sys/fs/tmpfs/tmpfs_vfsops.c
+++ sys/fs/tmpfs/tmpfs_vfsops.c
@@ -566,24 +566,26 @@
tmpfs_fhtovp(struct mount *mp, struct fid *fhp, int flags,
struct vnode **vpp)
{
- struct tmpfs_fid *tfhp;
+ struct tmpfs_fid_data tfd;
struct tmpfs_mount *tmp;
struct tmpfs_node *node;
int error;
+ if (fhp->fid_len != sizeof(struct tmpfs_fid_data))
+ return (EINVAL);
+
+ /* See comment in tmpfs_vptofh regarding fid_data offset. */
+ memcpy(&tfd, fhp->fid_data, fhp->fid_len);
+
tmp = VFS_TO_TMPFS(mp);
- tfhp = (struct tmpfs_fid *)fhp;
- if (tfhp->tf_len != sizeof(struct tmpfs_fid))
+ if (tfd.tfd_id >= tmp->tm_nodes_max)
return (EINVAL);
- if (tfhp->tf_id >= tmp->tm_nodes_max)
- return (EINVAL);
-
TMPFS_LOCK(tmp);
LIST_FOREACH(node, &tmp->tm_nodes_used, tn_entries) {
- if (node->tn_id == tfhp->tf_id &&
- node->tn_gen == tfhp->tf_gen) {
+ if (node->tn_id == tfd.tfd_id &&
+ node->tn_gen == tfd.tfd_gen) {
tmpfs_ref_node(node);
break;
}
Index: sys/fs/tmpfs/tmpfs_vnops.c
===================================================================
--- sys/fs/tmpfs/tmpfs_vnops.c
+++ sys/fs/tmpfs/tmpfs_vnops.c
@@ -1435,16 +1435,29 @@
static int
tmpfs_vptofh(struct vop_vptofh_args *ap)
+/*
+vop_vptofh {
+ IN struct vnode *a_vp;
+ IN struct fid *a_fhp;
+};
+*/
{
- struct tmpfs_fid *tfhp;
+ struct tmpfs_fid_data tfd;
struct tmpfs_node *node;
+ struct fid *fhp;
- tfhp = (struct tmpfs_fid *)ap->a_fhp;
node = VP_TO_TMPFS_NODE(ap->a_vp);
+ fhp = ap->a_fhp;
+ fhp->fid_len = sizeof(tfd);
- tfhp->tf_len = sizeof(struct tmpfs_fid);
- tfhp->tf_id = node->tn_id;
- tfhp->tf_gen = node->tn_gen;
+ /*
+ * fid_data is at a 32-bit offset in struct fid. Accessing
+ * struct tmpfs_fid_data's 64-bit fields through an unaligned pointer
+ * is undefined behavior. Copy the struct from the stack instead.
+ */
+ tfd.tfd_id = node->tn_id;
+ tfd.tfd_gen = node->tn_gen;
+ memcpy(fhp->fid_data, &tfd, fhp->fid_len);
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 1, 4:32 PM (2 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30682877
Default Alt Text
D25077.id72486.diff (2 KB)

Event Timeline