moby / buildkit

concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
https://github.com/moby/moby/issues/34227
Apache License 2.0
8.09k stars 1.14k forks source link

bboltcachestorage: only delete link after releasing result #5116

Closed fanjiyun closed 3 months ago

fanjiyun commented 3 months ago

If the result exists but the link has been deleted, it will cause the result to never be released, ultimately leading to data leakage.

tonistiigi commented 3 months ago

Do you have an example testcase that reproduces this scenario?

fanjiyun commented 3 months ago
  1. init:

    buildctl du
    ID  RECLAIMABLE SIZE    LAST ACCESSED
    Reclaimable:    0B
    Total:      0B
  2. buildctl build with Dockerfile:

    FROM huaixi/busybox
    RUN echo "hello world"
  3. buildctl build again with the same basic image, and the Dockerfile is:

    FROM busybox
    RUN echo "hello hello"
  4. buildctl du

    ID                                  RECLAIMABLE SIZE    LAST ACCESSED
    4nk2b8x63h9jxcxkffdnrjuc6                                               true        2.11MB
    lh6l9v9gq6c65ttetl92pxqcl*                                              true        16.38kB
    8rmrvscrhx0zecj19wgb7qh8n*                                              true        16.38kB
    3d0mik02mdf70wewf3x85wpxj*                                              true        8.19kB
    ts1az0q1defw1b5vjfyd84a0x*                                              true        4.10kB
    Reclaimable:    2.16MB
    Total:      2.16MB
  5. execute buildctl prune --keep-storage 2.12 to delete child results

    #buildctl du
    ID                                  RECLAIMABLE SIZE    LAST ACCESSED
    4nk2b8x63h9jxcxkffdnrjuc6                                               true        2.11MB
    ts1az0q1defw1b5vjfyd84a0x*                                              true        4.10kB
    Reclaimable:    2.12MB
    Total:      2.12MB

    now, we can found this two child results have been deleted:

    lh6l9v9gq6c65ttetl92pxqcl (Description: /bin/sh -c echo "hello hello")
    8rmrvscrhx0zecj19wgb7qh8n (Description: /bin/sh -c echo "hello world")

and parent result 4nk2b8x63h9jxcxkffdnrjuc6 (Description: pulled from buysbox...)exists

  1. view cache.db, we can found result 93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6 exists, but link id is deleted

    
    >>> cd _byresult
    / -> _byresult
    >>> ls
    [Bucket]    93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6
    [Bucket]    93bzqojj02l3lq3ckohg44brf::siz3zw0bdqms3oulcg646rtij
    
    Total 2 buckets and 0 keys

cd 93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6 / -> _byresult -> 93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6 ls [Key] sha256:4aa8794b66b4325e7210a7c4a6fe388cbb27f3929612d3d32169ea035c995c6d= [Key] sha256:809a9a7b9cc934b989047bfdfc9dd6f981a87339186f3c6de68ee36467365373=

Total 0 buckets and 2 keys

/ -> _result

ls [Bucket] random:498ca481485074b2c396b191e645df9f19916aae853f1296c94c214557b5cc70 [Bucket] sha256:4aa8794b66b4325e7210a7c4a6fe388cbb27f3929612d3d32169ea035c995c6d [Bucket] sha256:809a9a7b9cc934b989047bfdfc9dd6f981a87339186f3c6de68ee36467365373

Total 3 buckets and 0 keys

cd _links / -> _links ls [Bucket] random:498ca481485074b2c396b191e645df9f19916aae853f1296c94c214557b5cc70

Total 1 buckets and 0 keys


7. now, execute `buildctl prune --all` to delete all results

buildctl du

ID RECLAIMABLE SIZE LAST ACCESSED Reclaimable: 0B Total: 0B


8. at last, we expect cache.db to be empty,but in reality, result `93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6`  remains

cache.db:

cd _byresult / -> _byresult ls [Bucket] 93bzqojj02l3lq3ckohg44brf::4nk2b8x63h9jxcxkffdnrjuc6

Total 1 buckets and 0 keys

/ -> _result

ls [Bucket] sha256:4aa8794b66b4325e7210a7c4a6fe388cbb27f3929612d3d32169ea035c995c6d [Bucket] sha256:809a9a7b9cc934b989047bfdfc9dd6f981a87339186f3c6de68ee36467365373

Total 2 buckets and 0 keys

cd _links / -> _links ls

Total 0 buckets and 0 keys