Fix crash due to index-out-of-bounds in feature translation
authorValentine Wallace <vwallace@protonmail.com>
Wed, 14 Jul 2021 20:23:38 +0000 (16:23 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Wed, 14 Jul 2021 22:55:17 +0000 (18:55 -0400)
This was reported by a user when trying to send a payment using the LDK
sample (specifically during route generation when translating a Features
from one context to another)

The problem was we didn't check T::KNOWN_FEATURE_MASK vec length before
indexing into it, due likely to the assumption that known feature vec
lengths are the same across contexts, when they may not be

lightning/src/ln/features.rs

index b459baf06580bff8414715b82c1845e7334c23ee..9d865d15ec2bbc6f11e8ce39b2c970a0f48d4314 100644 (file)
@@ -490,13 +490,14 @@ impl<T: sealed::Context> Features<T> {
        /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are
        /// included in the result.
        fn to_context_internal<C: sealed::Context>(&self) -> Features<C> {
-               let byte_count = C::KNOWN_FEATURE_MASK.len();
+               let from_byte_count = T::KNOWN_FEATURE_MASK.len();
+               let to_byte_count = C::KNOWN_FEATURE_MASK.len();
                let mut flags = Vec::new();
                for (i, byte) in self.flags.iter().enumerate() {
-                       if i < byte_count {
-                               let known_source_features = T::KNOWN_FEATURE_MASK[i];
-                               let known_target_features = C::KNOWN_FEATURE_MASK[i];
-                               flags.push(byte & known_source_features & known_target_features);
+                       if i < from_byte_count && i < to_byte_count {
+                               let from_known_features = T::KNOWN_FEATURE_MASK[i];
+                               let to_known_features = C::KNOWN_FEATURE_MASK[i];
+                               flags.push(byte & from_known_features & to_known_features);
                        }
                }
                Features::<C> { flags, mark: PhantomData, }