#define INTERVAL_TREE_ROOT RB_ROOT
#endif /* HAVE_INTERVAL_TREE_CACHED */
+#ifndef unsafe_memcpy
+#define unsafe_memcpy(to, from, size, reason) memcpy((to), (from), (size))
+#endif
+
+#define FLEXIBLE_OBJECT \
+ "Struct contains a flexible member, the size of object is checked" \
+ "and can be safely copied in a single memcpy()"
+
#endif /* _LIBCFS_LIBCFS_H_ */
__u32 pi_features;
lnet_pid_t pi_pid;
__u32 pi_nnis; /* number of nid4 entries */
- struct lnet_ni_status pi_ni[0];
+ struct lnet_ni_status pi_ni[];
} __attribute__((packed));
#define LNET_PING_INFO_HDR_SIZE \
BUILD_BUG_ON((int)offsetof(struct lnet_ping_info, pi_nnis) != 12);
BUILD_BUG_ON((int)sizeof(((struct lnet_ping_info *)0)->pi_nnis) != 4);
BUILD_BUG_ON((int)offsetof(struct lnet_ping_info, pi_ni) != 16);
- BUILD_BUG_ON((int)sizeof(((struct lnet_ping_info *)0)->pi_ni) != 0);
+ BUILD_BUG_ON(offsetof(struct lnet_ping_info, pi_ni) != sizeof(struct lnet_ping_info));
/* Acceptor connection request */
BUILD_BUG_ON(LNET_PROTO_ACCEPTOR_VERSION != 1);
}
/* Success */
- memcpy(&lp->lp_data->pb_info, &pbuf->pb_info, infobytes);
+ unsafe_memcpy(&lp->lp_data->pb_info, &pbuf->pb_info, infobytes,
+ FLEXIBLE_OBJECT);
lp->lp_state |= LNET_PEER_DATA_PRESENT;
CDEBUG(D_NET, "Received Push %s %u\n",
libcfs_nidstr(&lp->lp_primary_nid),
#define STRINGIFY(a) #a
+#define CHECK_BUILD_TEST(a) \
+ printf(" BUILD_BUG_ON("#a");\n")
+
#define CHECK_DEFINE(a) \
do { \
printf (" BUILD_BUG_ON("#a" != "STRINGIFY(a)");\n"); \
CHECK_VALUE((int)sizeof(((s *)0)->m)); \
} while (0)
+#define CHECK_MEMBER_IS_FLEXIBLE(s, m) \
+do { \
+ CHECK_MEMBER_OFFSET(s, m); \
+ CHECK_BUILD_TEST(offsetof(struct s, m) != sizeof(struct s)); \
+} while (0)
+
#define CHECK_MEMBER(s,m) \
do { \
CHECK_MEMBER_OFFSET(s, m); \
CHECK_MEMBER(struct lnet_ping_info, pi_features);
CHECK_MEMBER(struct lnet_ping_info, pi_pid);
CHECK_MEMBER(struct lnet_ping_info, pi_nnis);
- CHECK_MEMBER(struct lnet_ping_info, pi_ni);
+ CHECK_MEMBER_IS_FLEXIBLE(struct lnet_ping_info, pi_ni);
}
void
CHECK_VALUE((int)sizeof(((s *)0)->m)); \
} while(0)
-#define CHECK_MEMBER_IS_FLEXIBLE_OR_ZERO_LENGTH(s, m) \
+#define CHECK_MEMBER_IS_FLEXIBLE(s, m) \
do { \
CHECK_MEMBER_OFFSET(s, m); \
CHECK_BUILD_TEST(offsetof(struct s, m) != sizeof(struct s)); \
CHECK_MEMBER(fiemap, fm_mapped_extents);
CHECK_MEMBER(fiemap, fm_extent_count);
CHECK_MEMBER(fiemap, fm_reserved);
- CHECK_MEMBER_IS_FLEXIBLE_OR_ZERO_LENGTH(fiemap, fm_extents);
+ CHECK_MEMBER_IS_FLEXIBLE(fiemap, fm_extents);
CHECK_CDEFINE(FIEMAP_FLAG_SYNC);
CHECK_CDEFINE(FIEMAP_FLAG_XATTR);