Require a non-0 number of non-empty paths when deserializing routes
authorMatt Corallo <git@bluematt.me>
Mon, 6 Feb 2023 21:43:10 +0000 (21:43 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 27 Feb 2023 22:31:11 +0000 (22:31 +0000)
When we read a `Route` (or a list of `RouteHop`s), we should never
have zero paths or zero `RouteHop`s in a path. As such, its fine to
simply reject these at deserialization-time. Technically this could
lead to something which we can generate not round-trip'ing
serialization, but that seems okay here.

lightning/src/ln/channelmanager.rs
lightning/src/routing/router.rs

index f07dc86f34d438b184f4eef2ad2aa7d932f8ff59..5d09741f4f085305d991945561645fd8d85cd227 100644 (file)
@@ -6745,7 +6745,7 @@ impl Readable for HTLCSource {
                        0 => {
                                let mut session_priv: crate::util::ser::RequiredWrapper<SecretKey> = crate::util::ser::RequiredWrapper(None);
                                let mut first_hop_htlc_msat: u64 = 0;
-                               let mut path = Some(Vec::new());
+                               let mut path: Option<Vec<RouteHop>> = Some(Vec::new());
                                let mut payment_id = None;
                                let mut payment_secret = None;
                                let mut payment_params = None;
@@ -6762,10 +6762,14 @@ impl Readable for HTLCSource {
                                        // instead.
                                        payment_id = Some(PaymentId(*session_priv.0.unwrap().as_ref()));
                                }
+                               if path.is_none() || path.as_ref().unwrap().is_empty() {
+                                       return Err(DecodeError::InvalidValue);
+                               }
+                               let path = path.unwrap();
                                Ok(HTLCSource::OutboundRoute {
                                        session_priv: session_priv.0.unwrap(),
                                        first_hop_htlc_msat,
-                                       path: path.unwrap(),
+                                       path,
                                        payment_id: payment_id.unwrap(),
                                        payment_secret,
                                        payment_params,
index b456e15a2d13cdce9b6090889e1e886ae17a997c..0a3c540607ae7ab27e8f3ad3a2411e320da43d86 100644 (file)
@@ -313,6 +313,7 @@ impl Readable for Route {
        fn read<R: io::Read>(reader: &mut R) -> Result<Route, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
                let path_count: u64 = Readable::read(reader)?;
+               if path_count == 0 { return Err(DecodeError::InvalidValue); }
                let mut paths = Vec::with_capacity(cmp::min(path_count, 128) as usize);
                for _ in 0..path_count {
                        let hop_count: u8 = Readable::read(reader)?;
@@ -320,6 +321,7 @@ impl Readable for Route {
                        for _ in 0..hop_count {
                                hops.push(Readable::read(reader)?);
                        }
+                       if hops.is_empty() { return Err(DecodeError::InvalidValue); }
                        paths.push(hops);
                }
                let mut payment_params = None;