CStr works with zero-terminated strings, and since you said your string isn't zero-terminated, that means CStr is the wrong thing to use.
Instead just do: std::str::from_utf8(std::slice::from_raw_parts(head, size)).unwrap()
Because to_string() is a method of ToString trait, which has impl<T: Display> ToString for T, and as Rust doesn't support impl specialization now, there's no way to override this impl for more specific case of &str. And as the only thing the impl<T: Display> ToString for T knows about T is it implements Display, it can use Display::fmt() method only to build string from T, which uses, well, heavy weight formatting machinery.
Maybe in the future Rust, when will get implementations specialization, this impl will be overriden for &str and you won't have to worry about it any more, but for now there's str::to_owned() method, created just because of this problem.