pxar: avoid taking ownership of xattrs, fcaps and quota_projid on corresponding restore functions.

By borrowing these objects we preserve the functionality but make sure
that ownership doesn't change, avoiding problems when contained within other
structs such as e.g. a buffer storing these attributes.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2019-08-01 12:13:07 +02:00 committed by Dietmar Maurer
parent 2c3891d1c3
commit 2be3eff5c3
2 changed files with 14 additions and 14 deletions

View File

@ -270,7 +270,7 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
// If fd is None, this indicates that we just want to skip over these entries (no restore). // If fd is None, this indicates that we just want to skip over these entries (no restore).
// If on the other hand there is Some(fd), restore the attributes on it. // If on the other hand there is Some(fd), restore the attributes on it.
if let Some(fd) = fd { if let Some(fd) = fd {
self.restore_xattrs_fcaps_fd(fd, xattrs, fcaps)?; self.restore_xattrs_fcaps_fd(fd, &xattrs, &fcaps)?;
let mut acl = acl::ACL::init(5)?; let mut acl = acl::ACL::init(5)?;
acl.add_entry_full(acl::ACL_USER_OBJ, None, mode_user_to_acl_permissions(entry.mode))?; acl.add_entry_full(acl::ACL_USER_OBJ, None, mode_user_to_acl_permissions(entry.mode))?;
@ -315,7 +315,7 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
} }
acl.set_file(&proc_path, acl::ACL_TYPE_DEFAULT)?; acl.set_file(&proc_path, acl::ACL_TYPE_DEFAULT)?;
} }
self.restore_quota_projid(fd, quota_projid)?; self.restore_quota_projid(fd, &quota_projid)?;
} }
Ok(head) Ok(head)
@ -325,16 +325,16 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
fn restore_xattrs_fcaps_fd( fn restore_xattrs_fcaps_fd(
&mut self, &mut self,
fd: RawFd, fd: RawFd,
xattrs: Vec<CaFormatXAttr>, xattrs: &Vec<CaFormatXAttr>,
fcaps: Option<CaFormatFCaps> fcaps: &Option<CaFormatFCaps>
) -> Result<(), Error> { ) -> Result<(), Error> {
for xattr in xattrs { for xattr in xattrs {
if let Err(err) = xattr::fsetxattr(fd, xattr) { if let Err(err) = xattr::fsetxattr(fd, &xattr) {
bail!("fsetxattr failed with error: {}", err); bail!("fsetxattr failed with error: {}", err);
} }
} }
if let Some(fcaps) = fcaps { if let Some(fcaps) = fcaps {
if let Err(err) = xattr::fsetxattr_fcaps(fd, fcaps) { if let Err(err) = xattr::fsetxattr_fcaps(fd, &fcaps) {
bail!("fsetxattr_fcaps failed with error: {}", err); bail!("fsetxattr_fcaps failed with error: {}", err);
} }
} }
@ -345,7 +345,7 @@ impl <'a, R: Read, F: Fn(&Path) -> Result<(), Error>> SequentialDecoder<'a, R, F
fn restore_quota_projid( fn restore_quota_projid(
&mut self, &mut self,
fd: RawFd, fd: RawFd,
projid: Option<CaFormatQuotaProjID> projid: &Option<CaFormatQuotaProjID>
) -> Result<(), Error> { ) -> Result<(), Error> {
if let Some(projid) = projid { if let Some(projid) = projid {
let mut fsxattr = fs::FSXAttr::default(); let mut fsxattr = fs::FSXAttr::default();

View File

@ -64,7 +64,7 @@ pub fn fgetxattr(fd: RawFd, name: &[u8]) -> Result<Vec<u8>, nix::errno::Errno> {
Ok(buffer) Ok(buffer)
} }
pub fn fsetxattr(fd: RawFd, xattr: CaFormatXAttr) -> Result<(), nix::errno::Errno> { pub fn fsetxattr(fd: RawFd, xattr: &CaFormatXAttr) -> Result<(), nix::errno::Errno> {
let mut name = xattr.name.clone(); let mut name = xattr.name.clone();
name.push('\0' as u8); name.push('\0' as u8);
let flags = 0 as libc::c_int; let flags = 0 as libc::c_int;
@ -79,7 +79,7 @@ pub fn fsetxattr(fd: RawFd, xattr: CaFormatXAttr) -> Result<(), nix::errno::Errn
Ok(()) Ok(())
} }
pub fn fsetxattr_fcaps(fd: RawFd, fcaps: CaFormatFCaps) -> Result<(), nix::errno::Errno> { pub fn fsetxattr_fcaps(fd: RawFd, fcaps: &CaFormatFCaps) -> Result<(), nix::errno::Errno> {
// TODO casync checks and removes capabilities if they are set // TODO casync checks and removes capabilities if they are set
let name = b"security.capability\0"; let name = b"security.capability\0";
let flags = 0 as libc::c_int; let flags = 0 as libc::c_int;
@ -159,15 +159,15 @@ mod tests {
value: b"err".to_vec(), value: b"err".to_vec(),
}; };
assert!(fsetxattr(fd, valid_user).is_ok()); assert!(fsetxattr(fd, &valid_user).is_ok());
assert!(fsetxattr(fd, valid_empty_value).is_ok()); assert!(fsetxattr(fd, &valid_empty_value).is_ok());
if nix::unistd::Uid::current() != nix::unistd::ROOT { if nix::unistd::Uid::current() != nix::unistd::ROOT {
assert_eq!(fsetxattr(fd, invalid_trusted), Err(Errno::EPERM)); assert_eq!(fsetxattr(fd, &invalid_trusted), Err(Errno::EPERM));
} }
assert_eq!(fsetxattr(fd, invalid_name_prefix), Err(Errno::EOPNOTSUPP)); assert_eq!(fsetxattr(fd, &invalid_name_prefix), Err(Errno::EOPNOTSUPP));
assert_eq!(fsetxattr(fd, invalid_name_length), Err(Errno::ERANGE)); assert_eq!(fsetxattr(fd, &invalid_name_length), Err(Errno::ERANGE));
let v0 = fgetxattr(fd, b"user.attribute0\0".as_ref()).unwrap(); let v0 = fgetxattr(fd, b"user.attribute0\0".as_ref()).unwrap();
let v1 = fgetxattr(fd, b"user.empty\0".as_ref()).unwrap(); let v1 = fgetxattr(fd, b"user.empty\0".as_ref()).unwrap();