mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
ANDROID: ashmem: Add toggle to ignore requests to deny PROT_READ mappings
Memfd does not support preventing a file from being mapped with PROT_READ, as ashmem does. It would be useful to expose a knob to userspace to change ashmem's behavior to match memfd to see if any issues arise during tests. Therefore, expose a tunable that userspace can use to cause ashmem to ignore requests to deny PROT_READ mappings. Bug: 111903542 Change-Id: Id4d1770e93a4fd5a6b3be04fd82c67d0eff0200e Signed-off-by: Isaac J. Manjarres <isaacmanjarres@google.com>
This commit is contained in:
@@ -107,6 +107,15 @@ static struct lock_class_key backing_shmem_inode_class;
|
|||||||
/* Enable unpinning feature by default to retain compatibility with existing behavior. */
|
/* Enable unpinning feature by default to retain compatibility with existing behavior. */
|
||||||
static bool unpinning_enable = true;
|
static bool unpinning_enable = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memfd does not allow removing permissions to map a buffer with PROT_READ. This variable
|
||||||
|
* is exposed as a tunable so that it can be used to make ashmem behave more like memfd for
|
||||||
|
* test purposes.
|
||||||
|
*
|
||||||
|
* It is set to false by default to retain compatibility with the original behavior of the driver.
|
||||||
|
*/
|
||||||
|
static bool ignore_unset_prot_read;
|
||||||
|
|
||||||
static inline unsigned long range_size(struct ashmem_range *range)
|
static inline unsigned long range_size(struct ashmem_range *range)
|
||||||
{
|
{
|
||||||
return range->pgend - range->pgstart + 1;
|
return range->pgend - range->pgstart + 1;
|
||||||
@@ -549,6 +558,10 @@ static int set_prot_mask(struct ashmem_area *asma, unsigned long prot)
|
|||||||
|
|
||||||
mutex_lock(&ashmem_mutex);
|
mutex_lock(&ashmem_mutex);
|
||||||
|
|
||||||
|
/* Ensure the buffer can only be mapped with PROT_READ iff it has that permission. */
|
||||||
|
if (ignore_unset_prot_read)
|
||||||
|
prot |= asma->prot_mask & PROT_READ;
|
||||||
|
|
||||||
/* the user can only remove, not add, protection bits */
|
/* the user can only remove, not add, protection bits */
|
||||||
if ((asma->prot_mask & prot) != prot) {
|
if ((asma->prot_mask & prot) != prot) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -934,6 +947,12 @@ static int unpinning_enable_open(struct inode *inode, struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ignore_unset_prot_read_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
file->private_data = &ignore_unset_prot_read;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t attr_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
static ssize_t attr_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
bool *attrp = file->private_data;
|
bool *attrp = file->private_data;
|
||||||
@@ -993,6 +1012,13 @@ static const struct file_operations unpinning_enable_fops = {
|
|||||||
.write = attr_write,
|
.write = attr_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct file_operations ignore_unset_prot_read_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = ignore_unset_prot_read_open,
|
||||||
|
.read = attr_read,
|
||||||
|
.write = attr_write,
|
||||||
|
};
|
||||||
|
|
||||||
static struct miscdevice ashmem_miscs[] = {
|
static struct miscdevice ashmem_miscs[] = {
|
||||||
{
|
{
|
||||||
.minor = MISC_DYNAMIC_MINOR,
|
.minor = MISC_DYNAMIC_MINOR,
|
||||||
@@ -1004,6 +1030,11 @@ static struct miscdevice ashmem_miscs[] = {
|
|||||||
.name = "ashmem_unpinning_enable",
|
.name = "ashmem_unpinning_enable",
|
||||||
.fops = &unpinning_enable_fops,
|
.fops = &unpinning_enable_fops,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.minor = MISC_DYNAMIC_MINOR,
|
||||||
|
.name = "ashmem_ignore_unset_prot_read",
|
||||||
|
.fops = &ignore_unset_prot_read_fops,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ashmem_init(void)
|
static int __init ashmem_init(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user