blob: 925820b9eb6a092c07972cbd24b88b17817cc99e [file]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use bitflags::bitflags;
use starnix_uapi::file_mode::Access;
use starnix_uapi::{PROT_EXEC, PROT_GROWSDOWN, PROT_READ, PROT_WRITE};
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ProtectionFlags: u32 {
const READ = PROT_READ;
const WRITE = PROT_WRITE;
const EXEC = PROT_EXEC;
const GROWSDOWN = PROT_GROWSDOWN;
}
}
impl ProtectionFlags {
pub const ACCESS_FLAGS: Self =
Self::from_bits_truncate(Self::READ.bits() | Self::WRITE.bits() | Self::EXEC.bits());
pub fn to_vmar_flags(self) -> zx::VmarFlags {
let mut vmar_flags = zx::VmarFlags::empty();
if self.contains(ProtectionFlags::READ) {
vmar_flags |= zx::VmarFlags::PERM_READ;
}
if self.contains(ProtectionFlags::WRITE) {
vmar_flags |= zx::VmarFlags::PERM_READ | zx::VmarFlags::PERM_WRITE;
}
if self.contains(ProtectionFlags::EXEC) {
vmar_flags |= zx::VmarFlags::PERM_EXECUTE | zx::VmarFlags::PERM_READ_IF_XOM_UNSUPPORTED;
}
vmar_flags
}
pub fn from_vmar_flags(vmar_flags: zx::VmarFlags) -> ProtectionFlags {
let mut prot_flags = ProtectionFlags::empty();
if vmar_flags.contains(zx::VmarFlags::PERM_READ) {
prot_flags |= ProtectionFlags::READ;
}
if vmar_flags.contains(zx::VmarFlags::PERM_WRITE) {
prot_flags |= ProtectionFlags::WRITE;
}
if vmar_flags.contains(zx::VmarFlags::PERM_EXECUTE) {
prot_flags |= ProtectionFlags::EXEC;
}
prot_flags
}
pub fn from_access_bits(prot: u32) -> Option<Self> {
if let Some(flags) = ProtectionFlags::from_bits(prot) {
if flags.contains(Self::ACCESS_FLAGS.complement()) { None } else { Some(flags) }
} else {
None
}
}
pub fn access_flags(&self) -> Self {
*self & Self::ACCESS_FLAGS
}
pub fn to_access(&self) -> Access {
let mut access = Access::empty();
if self.contains(ProtectionFlags::READ) {
access |= Access::READ;
}
if self.contains(ProtectionFlags::WRITE) {
access |= Access::WRITE;
}
if self.contains(ProtectionFlags::EXEC) {
access |= Access::EXEC;
}
access
}
}