Whamcloud - gitweb
LU-16509 lnet: quash memcpy WARN_ONCE false positive 01/49801/7
authorShaun Tancheff <shaun.tancheff@hpe.com>
Fri, 27 Jan 2023 07:08:23 +0000 (01:08 -0600)
committerOleg Drokin <green@whamcloud.com>
Wed, 8 Mar 2023 03:26:32 +0000 (03:26 +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.

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/fs/lustre-release/+/49801
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
libcfs/include/libcfs/libcfs.h
lnet/include/uapi/linux/lnet/lnet-idl.h
lnet/lnet/api-ni.c
lnet/lnet/peer.c
lnet/utils/wirecheck.c
lustre/utils/wirecheck.c

index 5a90865..7b552d4 100644 (file)
@@ -133,4 +133,12 @@ void libcfs_vfree_atomic(const void *addr);
 #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_ */
index ff44538..450c66a 100644 (file)
@@ -309,7 +309,7 @@ struct lnet_ping_info {
        __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 \
index c0ce984..58ebd4d 100644 (file)
@@ -952,7 +952,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));
 
        /* Acceptor connection request */
        BUILD_BUG_ON(LNET_PROTO_ACCEPTOR_VERSION != 1);
index 6c2cedb..37ffb23 100644 (file)
@@ -2440,7 +2440,8 @@ void lnet_peer_push_event(struct lnet_event *ev)
        }
 
        /* 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),
index 4edc523..e67d75c 100644 (file)
@@ -58,6 +58,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");     \
@@ -78,6 +81,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);              \
@@ -194,7 +203,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 c5d0590..5b910c9 100644 (file)
@@ -145,7 +145,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));    \
@@ -2238,7 +2238,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);