Browse Source

Merge pull request #621 from marysaka/fix/uprobe-debian-10

aya: Add support for old ld.so.cache format
Alessandro Decina 1 năm trước cách đây
mục cha
commit
41fe944a1a
1 tập tin đã thay đổi với 48 bổ sung18 xóa
  1. 48 18
      aya/src/programs/uprobe.rs

+ 48 - 18
aya/src/programs/uprobe.rs

@@ -29,7 +29,8 @@ lazy_static! {
     static ref LD_SO_CACHE: Result<LdSoCache, Arc<io::Error>> =
         LdSoCache::load(LD_SO_CACHE_FILE).map_err(Arc::new);
 }
-const LD_SO_CACHE_HEADER: &str = "glibc-ld.so.cache1.1";
+const LD_SO_CACHE_HEADER_OLD: &str = "ld.so-1.7.0\0";
+const LD_SO_CACHE_HEADER_NEW: &str = "glibc-ld.so.cache1.1";
 
 /// An user space probe.
 ///
@@ -267,36 +268,65 @@ impl LdSoCache {
             Ok(i32::from_ne_bytes(buf))
         };
 
-        let mut buf = [0u8; LD_SO_CACHE_HEADER.len()];
+        // Check for new format
+        let mut buf = [0u8; LD_SO_CACHE_HEADER_NEW.len()];
         cursor.read_exact(&mut buf)?;
         let header = std::str::from_utf8(&buf).map_err(|_| {
             io::Error::new(io::ErrorKind::InvalidData, "invalid ld.so.cache header")
         })?;
-        if header != LD_SO_CACHE_HEADER {
-            return Err(io::Error::new(
-                io::ErrorKind::InvalidData,
-                "invalid ld.so.cache header",
-            ));
+
+        let new_format = header == LD_SO_CACHE_HEADER_NEW;
+
+        // Check for old format
+        if !new_format {
+            cursor.set_position(0);
+            let mut buf = [0u8; LD_SO_CACHE_HEADER_OLD.len()];
+            cursor.read_exact(&mut buf)?;
+            let header = std::str::from_utf8(&buf).map_err(|_| {
+                io::Error::new(io::ErrorKind::InvalidData, "invalid ld.so.cache header")
+            })?;
+
+            if header != LD_SO_CACHE_HEADER_OLD {
+                return Err(io::Error::new(
+                    io::ErrorKind::InvalidData,
+                    "invalid ld.so.cache header",
+                ));
+            }
         }
 
         let num_entries = read_u32(&mut cursor)?;
-        let _str_tab_len = read_u32(&mut cursor)?;
-        cursor.consume(5 * mem::size_of::<u32>());
+
+        if new_format {
+            cursor.consume(6 * mem::size_of::<u32>());
+        }
+
+        let offset = if !new_format {
+            cursor.position() as usize + num_entries as usize * 12
+        } else {
+            0
+        };
 
         let mut entries = Vec::new();
         for _ in 0..num_entries {
             let flags = read_i32(&mut cursor)?;
             let k_pos = read_u32(&mut cursor)? as usize;
             let v_pos = read_u32(&mut cursor)? as usize;
-            cursor.consume(12);
-            let key =
-                unsafe { CStr::from_ptr(cursor.get_ref()[k_pos..].as_ptr() as *const c_char) }
-                    .to_string_lossy()
-                    .into_owned();
-            let value =
-                unsafe { CStr::from_ptr(cursor.get_ref()[v_pos..].as_ptr() as *const c_char) }
-                    .to_string_lossy()
-                    .into_owned();
+
+            if new_format {
+                cursor.consume(12);
+            }
+
+            let key = unsafe {
+                CStr::from_ptr(cursor.get_ref()[offset + k_pos..].as_ptr() as *const c_char)
+            }
+            .to_string_lossy()
+            .into_owned();
+            let value = unsafe {
+                CStr::from_ptr(cursor.get_ref()[offset + v_pos..].as_ptr() as *const c_char)
+            }
+            .to_string_lossy()
+            .into_owned();
+
             entries.push(CacheEntry {
                 key,
                 value,