Skip to content

Commit 987143a

Browse files
bors[bot]kevinmehalleldruin
authored
Merge #78
78: Fix unsound lifetime on LinuxI2CMessage r=eldruin a=kevinmehall The following code currently compiles, but passes a dangling pointer to the kernel, which will write to deallocated memory. ```rust extern crate i2cdev; use i2cdev::core::*; use i2cdev::linux::{LinuxI2CBus, LinuxI2CMessage}; const SLAVE_ADDR: u16 = 0x57; fn main() { let mut dev = LinuxI2CBus::new("/dev/i2c-1").unwrap(); let mut v = vec![0, 0, 0]; let mut msgs = [ LinuxI2CMessage::write(&[0x01]).with_address(SLAVE_ADDR), LinuxI2CMessage::read(&mut v).with_address(SLAVE_ADDR), ]; drop(v); // Now pointer in in the message is pointing to the deallocated Vec dev.transfer(&mut msgs).unwrap(); } ``` The lifetime parameter on the type alias doesn't do anything ([arguably a rustc bug that this is not an error](rust-lang/rust#82365)). The internal `i2c_msg` type without a lifetime parameter of its own does not actually enforce that the borrowed buffer is still valid at the time it is passed to the ioctl. Co-authored-by: Kevin Mehall <km@kevinmehall.net> Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
2 parents f832946 + c7fc26e commit 987143a

File tree

6 files changed

+22
-12
lines changed

6 files changed

+22
-12
lines changed

.github/bors.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ required_approvals = 1
44
status = [
55
"CI (stable, x86_64-unknown-linux-gnu)",
66
"CI (stable, armv7-unknown-linux-gnueabihf)",
7-
"CI (1.46.0, x86_64-unknown-linux-gnu)",
7+
"CI (1.60.0, x86_64-unknown-linux-gnu)",
88
"CI-macOS (stable, x86_64-apple-darwin)",
9-
"CI-macOS (1.46.0, x86_64-apple-darwin)",
9+
"CI-macOS (1.60.0, x86_64-apple-darwin)",
1010
]

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020

2121
include:
2222
# Test MSRV
23-
- rust: 1.46.0
23+
- rust: 1.60.0
2424
TARGET: x86_64-unknown-linux-gnu
2525

2626
# Test nightly but don't fail
@@ -61,7 +61,7 @@ jobs:
6161

6262
strategy:
6363
matrix:
64-
rust: [stable, 1.46.0]
64+
rust: [stable, 1.60.0]
6565
TARGET: [x86_64-apple-darwin]
6666

6767
steps:

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
1212
- Updated nix to version `0.25`.
1313
- Updated nix to version `0.24`; only use the `ioctl` feature.
1414
- Use `File.read_exact` instead of `File.read` in `LinuxI2CDevice.read` so that the buffer is filled.
15+
- Fix the lifetime parameter on `LinuxI2CMessage` to ensure that it does not outlive the buffer it points to.
16+
- Updated MSRV to 1.60.0.
1517

1618
## [v0.5.1] - 2021-11-22
1719

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ cross-compile. See https://github.com/japaric/rust-cross for pointers.
5353

5454
## Minimum Supported Rust Version (MSRV)
5555

56-
This crate is guaranteed to compile on stable Rust 1.46.0 and up. It *might*
56+
This crate is guaranteed to compile on stable Rust 1.60.0 and up. It *might*
5757
compile with older versions but that may change in any new patch release.
5858

5959
## License

src/ffi.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
1313
use nix;
1414
use std::io::Cursor;
15+
use std::marker::PhantomData;
1516
use std::mem;
1617
use std::os::unix::prelude::*;
1718
use std::ptr;
1819

1920
pub type I2CError = nix::Error;
2021

22+
/// Linux I2C message
2123
#[repr(C)]
22-
pub struct i2c_msg {
24+
pub struct i2c_msg<'a> {
2325
/// slave address
2426
pub(crate) addr: u16,
2527
/// serialized I2CMsgFlags
@@ -28,6 +30,8 @@ pub struct i2c_msg {
2830
pub(crate) len: u16,
2931
/// pointer to msg data
3032
pub(crate) buf: *const u8,
33+
34+
pub(crate) _p: PhantomData<&'a mut [u8]>,
3135
}
3236

3337
bitflags! {
@@ -143,9 +147,9 @@ pub struct i2c_smbus_ioctl_data {
143147
/// This is the structure as used in the I2C_RDWR ioctl call
144148
// see linux/i2c-dev.h
145149
#[repr(C)]
146-
pub struct i2c_rdwr_ioctl_data {
150+
pub struct i2c_rdwr_ioctl_data<'a> {
147151
// struct i2c_msg __user *msgs;
148-
msgs: *mut i2c_msg,
152+
msgs: *mut i2c_msg<'a>,
149153
// __u32 nmsgs;
150154
nmsgs: u32,
151155
}

src/linux.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::fs::File;
1515
use std::fs::OpenOptions;
1616
use std::io;
1717
use std::io::prelude::*;
18+
use std::marker::PhantomData;
1819
use std::os::unix::prelude::*;
1920
use std::path::Path;
2021

@@ -315,8 +316,7 @@ impl LinuxI2CBus {
315316
}
316317
}
317318

318-
/// Linux I2C message
319-
pub type LinuxI2CMessage<'a> = ffi::i2c_msg;
319+
pub use ffi::i2c_msg as LinuxI2CMessage;
320320

321321
impl<'a> I2CTransfer<'a> for LinuxI2CBus {
322322
type Error = LinuxI2CError;
@@ -354,21 +354,23 @@ bitflags! {
354354
}
355355

356356
impl<'a> I2CMessage<'a> for LinuxI2CMessage<'a> {
357-
fn read(data: &'a mut [u8]) -> LinuxI2CMessage {
357+
fn read(data: &'a mut [u8]) -> LinuxI2CMessage<'a> {
358358
Self {
359359
addr: 0, // will be filled later
360360
flags: I2CMessageFlags::READ.bits(),
361361
len: data.len() as u16,
362362
buf: data.as_ptr(),
363+
_p: PhantomData,
363364
}
364365
}
365366

366-
fn write(data: &'a [u8]) -> LinuxI2CMessage {
367+
fn write(data: &'a [u8]) -> LinuxI2CMessage<'a> {
367368
Self {
368369
addr: 0, // will be filled later
369370
flags: I2CMessageFlags::empty().bits(),
370371
len: data.len() as u16,
371372
buf: data.as_ptr(),
373+
_p: PhantomData,
372374
}
373375
}
374376
}
@@ -381,6 +383,7 @@ impl<'a> LinuxI2CMessage<'a> {
381383
flags: self.flags,
382384
len: self.len,
383385
buf: self.buf,
386+
_p: PhantomData,
384387
}
385388
}
386389

@@ -391,6 +394,7 @@ impl<'a> LinuxI2CMessage<'a> {
391394
flags: flags.bits(),
392395
len: self.len,
393396
buf: self.buf,
397+
_p: PhantomData,
394398
}
395399
}
396400
}

0 commit comments

Comments
 (0)