Solidity Storage Array Bugs | Blog của Ethereum Foundation

Rate this post

Thông báo lỗi mảng lưu trữ Solidity

Bài đăng trên blog này nói về hai lỗi được kết nối với các mảng lưu trữ không liên quan đến nhau. Cả hai đều đã có mặt trong trình biên dịch từ lâu và bây giờ mới được phát hiện mặc dù một hợp đồng có chứa chúng sẽ rất có thể hiển thị trục trặc trong các thử nghiệm.

Daenam Kim với sự giúp đỡ từ Nguyên Phạmcả hai từ Curvegrid đã phát hiện ra sự cố trong đó dữ liệu không hợp lệ được lưu trữ liên quan đến mảng các số nguyên có dấu.

Lỗi này đã xuất hiện kể từ Solidity 0.4.7 và chúng tôi coi đây là lỗi nghiêm trọng hơn trong số hai lỗi. Nếu các mảng này sử dụng số nguyên âm trong một tình huống nhất định, nó sẽ gây ra hỏng dữ liệu và do đó lỗi sẽ dễ phát hiện.

Thông qua chương trình tiền thưởng lỗi Ethereum, chúng tôi đã nhận được một báo cáo về một lỗ hổng trong bộ mã hóa ABI thử nghiệm mới (được gọi là ABIEncoderV2). Bộ mã hóa ABI mới vẫn được đánh dấu là thử nghiệm, nhưng chúng tôi nghĩ rằng điều này xứng đáng là một thông báo nổi bật vì nó đã được sử dụng trên mạng chính. Tín dụng cho Ming Chuan Lin (trong tổng số https://www.secondstate.io) để phát hiện và sửa lỗi!

Các Bản phát hành 0,5.10 chứa các bản sửa lỗi. Hiện tại, chúng tôi không có kế hoạch xuất bản bản sửa lỗi cho dòng Solidity 0.4.x cũ, nhưng chúng tôi có thể thực hiện nếu có nhu cầu phổ biến.

Cả hai lỗi đều có thể dễ dàng nhìn thấy trong các thử nghiệm chạm vào các đường dẫn mã có liên quan.

Thông tin chi tiết về hai lỗi có thể được tìm thấy bên dưới.

Lỗi mảng số nguyên đã ký

Ai nên quan tâm

Nếu bạn đã triển khai các hợp đồng sử dụng mảng số nguyên đã ký trong bộ nhớ và chỉ định trực tiếp

  • một mảng chữ có ít nhất một giá trị âm trong đó (x = [-1, -2, -3];) hoặc
  • một mảng hiện có của một khác nhau kiểu số nguyên có dấu

đối với nó, điều này sẽ dẫn đến hỏng dữ liệu trong mảng lưu trữ.

Các hợp đồng chỉ chỉ định các phần tử mảng riêng lẻ (nghĩa là với x[2] = -1;) không bị ảnh hưởng.

Cách kiểm tra xem hợp đồng có dễ bị tổn thương hay không

Nếu bạn sử dụng mảng số nguyên có dấu trong bộ nhớ, hãy thử chạy các bài kiểm tra trong đó bạn sử dụng các giá trị âm. Hiệu quả phải là giá trị thực được lưu trữ là dương thay vì âm.

Nếu bạn có hợp đồng đáp ứng các điều kiện này và muốn xác minh xem liệu hợp đồng có thực sự dễ bị tấn công hay không, bạn có thể liên hệ với chúng tôi qua [email protected].

Chi tiết kỹ thuật

Mảng lưu trữ có thể được gán từ các mảng có kiểu khác nhau. Trong hoạt động sao chép và gán này, một chuyển đổi kiểu được thực hiện trên mỗi phần tử. Ngoài việc chuyển đổi, đặc biệt nếu kiểu số nguyên có dấu ngắn hơn 256 bit, một số bit nhất định của giá trị phải được xóa đi để chuẩn bị cho việc lưu trữ nhiều giá trị trong cùng một vùng lưu trữ.

Các bit nào đến 0 được xác định không chính xác từ nguồn và không phải loại đích. Điều này dẫn đến quá nhiều bit bị xóa. Đặc biệt, bit dấu sẽ bằng không, làm cho giá trị dương.

Lỗi mảng ABIEncoderV2

Ai nên quan tâm

Nếu bạn đã triển khai các hợp đồng sử dụng bộ mã hóa ABI thử nghiệm V2, thì những hợp đồng đó có thể bị ảnh hưởng. Điều này có nghĩa là chỉ các hợp đồng sử dụng lệnh sau trong mã nguồn mới có thể bị ảnh hưởng:

pragma experimental ABIEncoderV2;

Ngoài ra, có một số yêu cầu để lỗi kích hoạt. Xem thêm chi tiết kỹ thuật bên dưới để biết thêm thông tin.

Cách kiểm tra xem hợp đồng có dễ bị tổn thương hay không

Lỗi chỉ xuất hiện khi đáp ứng tất cả các điều kiện sau:

  • Dữ liệu lưu trữ liên quan đến mảng hoặc cấu trúc được gửi trực tiếp đến một lệnh gọi hàm bên ngoài, tới abi.encode hoặc dữ liệu sự kiện mà không cần gán trước cho biến cục bộ (bộ nhớ) AND
  • dữ liệu này hoặc chứa một mảng cấu trúc hoặc một mảng các mảng có kích thước tĩnh (tức là ít nhất là hai chiều).

Ngoài ra, trong trường hợp sau, mã của bạn KHÔNG bị ảnh hưởng:

  • nếu bạn chỉ trả lại dữ liệu như vậy và không sử dụng nó trong abi.encodecuộc gọi bên ngoài hoặc dữ liệu sự kiện.

Những hậu quả có thể xảy ra

Đương nhiên, bất kỳ lỗi nào cũng có thể gây ra những hậu quả khác nhau tùy thuộc vào quy trình điều khiển chương trình, nhưng chúng tôi cho rằng điều này có nhiều khả năng dẫn đến sự cố hơn là khả năng khai thác.

Lỗi, khi được kích hoạt, trong một số trường hợp nhất định sẽ gửi các tham số bị hỏng trên các lệnh gọi phương thức tới các hợp đồng khác.

Chi tiết kỹ thuật

Trong quá trình mã hóa, bộ mã hóa ABI thử nghiệm không tiến đúng cách đến phần tử tiếp theo trong một mảng trong trường hợp các phần tử chiếm nhiều hơn một vị trí trong bộ nhớ.

Đây chỉ là trường hợp cho các phần tử là cấu trúc hoặc mảng có kích thước tĩnh. Các mảng của mảng có kích thước động hoặc của các kiểu dữ liệu cơ bản không bị ảnh hưởng.

Hiệu ứng cụ thể mà bạn sẽ thấy là dữ liệu được “dịch chuyển” trong mảng được mã hóa: Nếu bạn có một mảng kiểu uint[2][] và nó chứa dữ liệu
[[1, 2], [3, 4], [5, 6]]sau đó nó sẽ được mã hóa thành [[1, 2], [2, 3], [3, 4]] bởi vì bộ mã hóa chỉ tiến thêm một khe giữa các phần tử thay vì hai.

Bài đăng này do @axic, @chriseth, @holiman cùng sáng tác

Thuc Quyen

Leave a Reply

Your email address will not be published. Required fields are marked *