Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexEntry path and flags not safe to expose directly #138

Closed
joshtriplett opened this issue May 7, 2016 · 8 comments
Closed

IndexEntry path and flags not safe to expose directly #138

joshtriplett opened this issue May 7, 2016 · 8 comments

Comments

@joshtriplett
Copy link
Member

joshtriplett commented May 7, 2016

In the underlying git_index_entry structure, the low 12 bits of flags define the length of the path (with 0xFFF indicating a need to search for a NUL terminator, which as far as I can tell must always exist for an in-memory structure regardless of length). IndexEntry exposes the path and flags fields directly, without handling NUL termination or length. An IndexEntry constructed in safe code can cause libgit2 to access memory it shouldn't and write that out as part of the path. For instance, I constructed an IndexEntry for a file "base", and the index on disk ended up with a file "basec6d", where "c6d" were characters of a recently handled short hash ID.

git2-rs needs to provide a safer wrapper for IndexEntry, making the safer fields available directly, but providing wrappers for the path, stage, and flags, to maintain consistency. Since IndexEntry won't have all of its fields available, it will also need an appropriate constructor. I'd suggest an IndexEntry::new that takes a Path, mode, and Option<Oid>.

@alexcrichton
Copy link
Member

Oh dear I had no idea!

@joshtriplett
Copy link
Member Author

Investigating more carefully, it looks like libgit2 might handle the length automatically, at least in git_index_add. But it's still not safe to expose path directly, because it must be NUL-terminated.

@alexcrichton
Copy link
Member

Yeah this sounds pretty bad all around, and IndexEntry may end up just needing a complete overhaul

@joshtriplett
Copy link
Member Author

joshtriplett commented May 11, 2016

A related issue I just ran into: if you read an IndexEntry using git2::Index::get_path, and then add that entry to another index using .git2::Index::add, that can read off the end of the .path field. Whatever safety property .add needs, the IndexEntry returned by .get_path doesn't seem to satisfy.

@alexcrichton
Copy link
Member

Oh dear, this appears to be extra bad then! Thanks for the reports!

Ah and I am indeed acrichto on IRC, sorry I missed your ping! I probably won't be able to get around to this until perhaps this weekend at the earliest, but if you want to try to tackle it ahead of time feel free as well!

@alexcrichton
Copy link
Member

Ok, can you try giving master a spin? If it works I'll publish a release

@joshtriplett
Copy link
Member Author

@alexcrichton Seems to work; I removed the workarounds I had for NUL handling, and everything seems functional.

I made one comment on the commit, regarding whether IndexEntry should have a Path instead of a Vec<u8> to make it explicit that it shouldn't have NUL handling. Otherwise, this looks good to me.

@alexcrichton
Copy link
Member

Ok, thanks for checking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants