提交 c7731567 编写于 作者: P Peng Wu 提交者: Yang Yingliang

mm: Introduce reliable flag for user task

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S
CVE: NA

------------------------------------------

Adding reliable flag for user task. User task with reliable flag can
only alloc memory from mirrored region. PF_RELIABLE is added to represent
the task's reliable flag.

- For init task, which is regarded as as special task which alloc memory
  from mirrored region.

- For normal user tasks, The reliable flag can be set via procfs interface
  shown as below and can be inherited via fork().

User can change a user task's reliable flag by

	$ echo [0/1] > /proc/<pid>/reliable

and check a user task's reliable flag by

	$ cat /proc/<pid>/reliable

Note, global init task's reliable file can not be accessed.
Signed-off-by: NPeng Wu <wupeng58@huawei.com>
Signed-off-by: NMa Wupeng <mawupeng1@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 b1f317c6
...@@ -1222,6 +1222,96 @@ static const struct file_operations proc_oom_score_adj_operations = { ...@@ -1222,6 +1222,96 @@ static const struct file_operations proc_oom_score_adj_operations = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
#ifdef CONFIG_MEMORY_RELIABLE
static inline int reliable_check(struct task_struct *task, struct pid *pid)
{
if (!mem_reliable_is_enabled())
return -EPERM;
if (is_global_init(task))
return -EPERM;
if (!task->mm || (task->flags & PF_KTHREAD) ||
(task->flags & PF_EXITING))
return -EPERM;
return 0;
}
static ssize_t reliable_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct task_struct *task = get_proc_task(file_inode(file));
struct pid *pid = proc_pid(file_inode(file));
char buffer[PROC_NUMBUF];
size_t len;
short val;
int err;
if (!task)
return -ESRCH;
err = reliable_check(task, pid);
if (err) {
put_task_struct(task);
return err;
}
val = task->flags & PF_RELIABLE ? 1 : 0;
put_task_struct(task);
len = snprintf(buffer, sizeof(buffer), "%hd\n", val);
return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
static ssize_t reliable_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct task_struct *task = get_proc_task(file_inode(file));
struct pid *pid = proc_pid(file_inode(file));
char buffer[PROC_NUMBUF];
int val;
int err;
if (!task)
return -ESRCH;
err = reliable_check(task, pid);
if (err)
goto out;
memset(buffer, 0, sizeof(buffer));
if (count > sizeof(buffer) - 1)
count = sizeof(buffer) - 1;
if (copy_from_user(buffer, buf, count)) {
err = -EFAULT;
goto out;
}
err = kstrtoint(strstrip(buffer), 0, &val);
if (err)
goto out;
if (val != 0 && val != 1) {
err = -EINVAL;
goto out;
}
if (val == 1)
task->flags |= PF_RELIABLE;
else
task->flags &= ~PF_RELIABLE;
out:
put_task_struct(task);
return err < 0 ? err : count;
}
static const struct file_operations proc_reliable_operations = {
.read = reliable_read,
.write = reliable_write,
.llseek = generic_file_llseek,
};
#endif
#ifdef CONFIG_AUDITSYSCALL #ifdef CONFIG_AUDITSYSCALL
#define TMPBUFLEN 11 #define TMPBUFLEN 11
static ssize_t proc_loginuid_read(struct file * file, char __user * buf, static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
...@@ -3029,6 +3119,9 @@ static const struct pid_entry tgid_base_stuff[] = { ...@@ -3029,6 +3119,9 @@ static const struct pid_entry tgid_base_stuff[] = {
ONE("oom_score", S_IRUGO, proc_oom_score), ONE("oom_score", S_IRUGO, proc_oom_score),
REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_MEMORY_RELIABLE
REG("reliable", S_IRUGO|S_IWUSR, proc_reliable_operations),
#endif
#ifdef CONFIG_AUDITSYSCALL #ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid", S_IRUGO, proc_sessionid_operations), REG("sessionid", S_IRUGO, proc_sessionid_operations),
...@@ -3419,6 +3512,9 @@ static const struct pid_entry tid_base_stuff[] = { ...@@ -3419,6 +3512,9 @@ static const struct pid_entry tid_base_stuff[] = {
ONE("oom_score", S_IRUGO, proc_oom_score), ONE("oom_score", S_IRUGO, proc_oom_score),
REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_MEMORY_RELIABLE
REG("reliable", S_IRUGO|S_IWUSR, proc_reliable_operations),
#endif
#ifdef CONFIG_AUDITSYSCALL #ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
REG("sessionid", S_IRUGO, proc_sessionid_operations), REG("sessionid", S_IRUGO, proc_sessionid_operations),
......
...@@ -1421,6 +1421,7 @@ extern struct pid *cad_pid; ...@@ -1421,6 +1421,7 @@ extern struct pid *cad_pid;
*/ */
#define PF_IDLE 0x00000002 /* I am an IDLE thread */ #define PF_IDLE 0x00000002 /* I am an IDLE thread */
#define PF_EXITING 0x00000004 /* Getting shut down */ #define PF_EXITING 0x00000004 /* Getting shut down */
#define PF_RELIABLE 0x00000008 /* Allocate from reliable memory */
#define PF_VCPU 0x00000010 /* I'm a virtual CPU */ #define PF_VCPU 0x00000010 /* I'm a virtual CPU */
#define PF_WQ_WORKER 0x00000020 /* I'm a workqueue worker */ #define PF_WQ_WORKER 0x00000020 /* I'm a workqueue worker */
#define PF_FORKNOEXEC 0x00000040 /* Forked but didn't exec */ #define PF_FORKNOEXEC 0x00000040 /* Forked but didn't exec */
......
...@@ -4571,6 +4571,9 @@ static inline void prepare_before_alloc(gfp_t *gfp_mask) ...@@ -4571,6 +4571,9 @@ static inline void prepare_before_alloc(gfp_t *gfp_mask)
if (gfp_ori & ___GFP_RELIABILITY) if (gfp_ori & ___GFP_RELIABILITY)
*gfp_mask |= ___GFP_RELIABILITY; *gfp_mask |= ___GFP_RELIABILITY;
if (current->flags & PF_RELIABLE || is_global_init(current))
*gfp_mask |= ___GFP_RELIABILITY;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册