Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix: BufferOverflow when BranchSession size too large #1552

Merged
merged 7 commits into from
Sep 8, 2019

Conversation

finalcola
Copy link
Contributor

Ⅰ. Describe what this PR did

fix BufferOverflowException when FileTransactionStoreManager write a big BranchSession(size > 16KB).

Ⅱ. Does this pull request fix one issue?

fixes #1551

#1551 (comment)

Ⅲ. Why don't you add test cases (unit test/integration test)?

public class FileTransactionStoreManagerTest {

    FileTransactionStoreManager fileTransactionStoreManager;

    @BeforeEach
    public void beforeAll() throws IOException {
        fileTransactionStoreManager = new FileTransactionStoreManager("~/my/tmp/test/seata", null);
    }

    @Test
    public void writeBigBytes() {
        BranchSession branchSession = new BranchSession();
        branchSession.setApplicationData(createBigStr(1024 * 16 - 36));
        fileTransactionStoreManager.writeSession(TransactionStoreManager.LogOperation.BRANCH_ADD, branchSession);
    }

    public String createBigStr(int size){
        byte[] bytes = new byte[size];
        for (int i = 0; i < size; i++) {
            bytes[i] = 'a';
        }
        return new String(bytes);
    }
}

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@codecov-io
Copy link

codecov-io commented Aug 28, 2019

Codecov Report

Merging #1552 into develop will decrease coverage by 0.03%.
The diff coverage is 0%.

Impacted file tree graph

@@              Coverage Diff              @@
##             develop    #1552      +/-   ##
=============================================
- Coverage      46.44%   46.41%   -0.04%     
  Complexity      1717     1717              
=============================================
  Files            350      350              
  Lines          12847    12847              
  Branches        1618     1618              
=============================================
- Hits            5967     5963       -4     
- Misses          6232     6234       +2     
- Partials         648      650       +2
Impacted Files Coverage Δ Complexity Δ
...server/store/file/FileTransactionStoreManager.java 45.99% <0%> (-1.4%) 19 <1> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e191caa...bfcabf4. Read the comment docs.

Copy link
Member

@slievrly slievrly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (bs.length + 4 )> int.max, how to process?

@finalcola
Copy link
Contributor Author

ByteBuffer byteBuffer = null;

        if (bs.length > MAX_WRITE_BUFFER_SIZE) {
            //allocateNew
            byteBuffer = ByteBuffer.allocateDirect(bs.length);
        } else {
            byteBuffer = writeBuffer;
            //recycle
            byteBuffer.clear();
        }
        byteBuffer.putInt(bs.length);
        byteBuffer.put(bs);
        return writeDataFileByBuffer(byteBuffer);

it's origin code.
when execute :

byteBuffer.putInt(bs.length);
byteBuffer.put(bs);

bytebuffer will write extra 4 byte content (bs.length), but when allocate DirectByteBuffer, the length of the DirectByteBuffer is bs.length ( should be bs.length +4 )

@slievrly
Copy link
Member

@finalcola public static ByteBuffer allocateDirect(int capacity) accept a int param, if bs.len<int.max but bs.len+4>int.max , it need to judge?

@finalcola
Copy link
Contributor Author

MAX_WRITE_BUFFER_SIZE is 16KB not int.max.
when bs.length>MAX_WRITE_BUFFER_SIZE, there will allocate a new ByteBuffer(size = bs.length).
but we put bs.length(int) and bs content into this ByteBuffer, so it will oversize 4B (bs.length) and cause BufferOverflowException.
@slievrly

@slievrly
Copy link
Member

@finalcola if (bs.length=int.max-1 ) ,can it run normally?

@finalcola
Copy link
Contributor Author

it can't , because byteBuffer always write extra 4 byte content(Larger than the allocated buffer).
@slievrly

@slievrly
Copy link
Member

it can't , because byteBuffer always write extra 4 byte content(Larger than the allocated buffer).
@slievrly

So do we need to add code to judge bs.length over int.max?

@finalcola
Copy link
Contributor Author

finalcola commented Aug 30, 2019

no,it's already judged before enter this method.

@slievrly
Copy link
Member

no,it's already judged before enter this method.

  1. private boolean writeDataFile(byte[] bs)
  2. call writeDataFile method with param byte[] bs.(int.max-3<bs.length<int.max)

@finalcola
Copy link
Contributor Author

so we should judge bs.length<=int.max-4?

Copy link
Member

@slievrly slievrly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zjinlei zjinlei changed the title bugfix: fix BufferOverflow when BranchSession size too large bugfix: BufferOverflow when BranchSession size too large Sep 3, 2019
@xingfudeshi xingfudeshi self-requested a review September 7, 2019 12:23
Copy link
Member

@xingfudeshi xingfudeshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@xingfudeshi xingfudeshi merged commit fce1c23 into apache:develop Sep 8, 2019
@wangliang181230 wangliang181230 added this to the 0.8.1 milestone Aug 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FileTransactionStoreManager.writeDataFile may cause BufferOverflowException
6 participants