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:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							2c3891d1c3
						
					
				
				
					commit
					2be3eff5c3
				
			@ -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, "a_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();
 | 
				
			||||||
 | 
				
			|||||||
@ -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();
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user