Whamcloud - gitweb
LU-16509 lnet: quash memcpy WARN_ONCE false positive
authorShaun Tancheff <shaun.tancheff@hpe.com>
Mon, 6 Mar 2023 15:33:51 +0000 (10:33 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Fri, 10 Mar 2023 19:56:06 +0000 (19:56 +0000)
Linux v6.1-rc1-4-g6f7630b1b5bc
  fortify: Capture __bos() results in const temp var

In lnet_peer_push_event() the memcpy triggers a WARN_ONCE
due to the flexible array at the end of
struct lnet_ping_info contained in struct lnet_ping_buffer

Use unsafe_memcpy() to avoid this false positive warning.

Lustre-change: https://review.whamcloud.com/49801
Lustre-commit: 18e24419599666bd536d072705052a8c64b681ab (tbd)

Test-Parameters: trivial
HPE-bug-id: LUS-11455
Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: I4aa8f38678cd1522004d98b58a3f440d8a38589c
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/50217
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
libcfs/include/libcfs/libcfs.h
lnet/include/uapi/linux/lnet/lnet-types.h
lnet/lnet/api-ni.c
lnet/lnet/peer.c
lnet/utils/wirecheck.c
lustre/utils/wirecheck.c

index bb4219d..fd170a4 100644 (file)
@@ -135,4 +135,12 @@ do {                                                                       \
 /* atomic-context safe vfree */
 void libcfs_vfree_atomic(const void *addr);
 
+#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_ */
index a5fc1d1..4ab1a02 100644 (file)
@@ -303,7 +303,7 @@ struct lnet_ping_info {
        __u32                   pi_features;
        lnet_pid_t              pi_pid;
        __u32                   pi_nnis;
-       struct lnet_ni_status   pi_ni[0];
+       struct lnet_ni_status   pi_ni[];
 } WIRE_ATTR;
 
 #define LNET_PING_INFO_SIZE(NNIDS) \
index 0cff451..2ba6e5e 100644 (file)
@@ -863,7 +863,7 @@ static void lnet_assert_wire_constants(void)
        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));
 }
 
 static const struct lnet_lnd *lnet_find_lnd_by_type(__u32 type)
index 4ed553c..6d5cc87 100644 (file)
@@ -2400,8 +2400,9 @@ void lnet_peer_push_event(struct lnet_event *ev)
        }
 
        /* Success */
-       memcpy(&lp->lp_data->pb_info, &pbuf->pb_info,
-              LNET_PING_INFO_SIZE(pbuf->pb_info.pi_nnis));
+       unsafe_memcpy(&lp->lp_data->pb_info, &pbuf->pb_info,
+                     LNET_PING_INFO_SIZE(pbuf->pb_info.pi_nnis),
+                     FLEXIBLE_OBJECT);
        lp->lp_state |= LNET_PEER_DATA_PRESENT;
        CDEBUG(D_NET, "Received Push %s %u\n",
               libcfs_nid2str(lp->lp_primary_nid),
index 98aaee9..b233b6f 100644 (file)
@@ -59,6 +59,9 @@ do {                                            \
 
 #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");     \
@@ -79,6 +82,12 @@ do {                                            \
         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);              \
@@ -189,7 +198,7 @@ check_lnet_ping_info(void)
        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
index abcee3f..e713a68 100644 (file)
@@ -144,7 +144,7 @@ do {                                                                \
        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));    \
@@ -2206,7 +2206,7 @@ check_ll_user_fiemap(void)
        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);