ALPHA: wire is a tool to deploy nixos systems wire.althaea.zone/
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

invalidate caches that reference garbage collected paths

+44 -12
+1
CHANGELOG.md
··· 14 14 ### Changed 15 15 16 16 - Fix a bug related to key filtering 17 + - Invalidate caches that reference garbage collected paths 17 18 18 19 ## [v1.0.0-beta.0] - 2025-12-02 19 20
+43 -12
wire/lib/src/cache/mod.rs
··· 1 1 // SPDX-License-Identifier: AGPL-3.0-or-later 2 2 // Copyright 2024-2025 wire Contributors 3 3 4 - use std::{env, path::PathBuf}; 4 + use std::{ 5 + env, 6 + path::{Path, PathBuf}, 7 + }; 5 8 6 9 use sqlx::{ 7 10 Pool, Sqlite, ··· 69 72 Some(Self { pool }) 70 73 } 71 74 75 + fn cache_invalid(store_path: &String) -> bool { 76 + let path = Path::new(store_path); 77 + 78 + // possible TOCTOU 79 + !path.exists() 80 + } 81 + 72 82 pub async fn get_hive(&self, prefetch: &FlakePrefetch) -> Option<Hive> { 73 - let cached_blob: Vec<u8> = sqlx::query_scalar!( 83 + struct Query { 84 + json_value: Vec<u8>, 85 + store_path: String, 86 + } 87 + 88 + let cached_blob = sqlx::query_as!( 89 + Query, 74 90 " 75 - select inspection_blobs.json_value from inspection_blobs 76 - join inspection_cache 77 - on inspection_cache.blob_id = inspection_blobs.id 78 - where inspection_cache.store_path = $1 79 - and inspection_cache.hash = $2 80 - and inspection_blobs.schema_version = $3 81 - limit 1 91 + select 92 + inspection_blobs.json_value, 93 + inspection_cache.store_path 94 + from 95 + inspection_blobs 96 + join inspection_cache on inspection_cache.blob_id = inspection_blobs.id 97 + where 98 + inspection_cache.store_path = $1 99 + and inspection_cache.hash = $2 100 + and inspection_blobs.schema_version = $3 101 + limit 102 + 1 82 103 ", 83 104 prefetch.store_path, 84 105 prefetch.hash, ··· 89 110 .inspect_err(|x| error!("failed to fetch cached hive: {x}")) 90 111 .ok()??; 91 112 92 - trace!("read {} bytes of zstd data from cache", cached_blob.len()); 113 + // the cached path may of been garbage collected, discard it 114 + // it is quite hard to replicate this bug but its occurred to me 115 + // atleast once 116 + if Self::cache_invalid(&cached_blob.store_path) { 117 + trace!("discarding cache that does not exist in the nix store"); 118 + } 93 119 94 - let json_string = zstd::decode_all(cached_blob.as_slice()) 120 + trace!( 121 + "read {} bytes of zstd data from cache", 122 + cached_blob.json_value.len() 123 + ); 124 + 125 + let json_string = zstd::decode_all(cached_blob.json_value.as_slice()) 95 126 .inspect_err(|err| error!("failed to decode cached zstd data: {err}")) 96 127 .ok()?; 97 128 98 129 trace!( 99 130 "inflated {} > {} in decoding", 100 - cached_blob.len(), 131 + cached_blob.json_value.len(), 101 132 json_string.len() 102 133 ); 103 134