cfg80211: Fix array-bounds warning in fragment copy 14/220814/1
authorMatthias Kaehlcke <mka@chromium.org>
Thu, 13 Apr 2017 17:05:04 +0000 (10:05 -0700)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 23 Dec 2019 07:37:55 +0000 (16:37 +0900)
commit aa1702dd162f420bf85ecef0c77686ef0dbc1496 upstream.

__ieee80211_amsdu_copy_frag intentionally initializes a pointer to
array[-1] to increment it later to valid values. clang rightfully
generates an array-bounds warning on the initialization statement.

Initialize the pointer to array[0] and change the algorithm from
increment before to increment after consume.

Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Cc: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[sw0312.kim: cherry-pick stable linux-4.9.y commit 4bb797afd7ba for gcc 9 build]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: Ibb581c74dc67fcc867f7fa58d20cb1b225caa852

net/wireless/util.c

index d5526fee8fa9f96ee297645533c33ae60d1d1ad2..e2312e34a7370e2806d74de400c427365f649a5f 100644 (file)
@@ -665,7 +665,7 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
                            int offset, int len)
 {
        struct skb_shared_info *sh = skb_shinfo(skb);
-       const skb_frag_t *frag = &sh->frags[-1];
+       const skb_frag_t *frag = &sh->frags[0];
        struct page *frag_page;
        void *frag_ptr;
        int frag_len, frag_size;
@@ -678,10 +678,10 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
 
        while (offset >= frag_size) {
                offset -= frag_size;
-               frag++;
                frag_page = skb_frag_page(frag);
                frag_ptr = skb_frag_address(frag);
                frag_size = skb_frag_size(frag);
+               frag++;
        }
 
        frag_ptr += offset;
@@ -693,12 +693,12 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
        len -= cur_len;
 
        while (len > 0) {
-               frag++;
                frag_len = skb_frag_size(frag);
                cur_len = min(len, frag_len);
                __frame_add_frag(frame, skb_frag_page(frag),
                                 skb_frag_address(frag), cur_len, frag_len);
                len -= cur_len;
+               frag++;
        }
 }