Add samsung specific changes
This commit is contained in:
@@ -90,14 +90,6 @@ config PROC_PAGE_MONITOR
|
||||
/proc/kpagecount, and /proc/kpageflags. Disabling these
|
||||
interfaces will reduce the size of the kernel by approximately 4kb.
|
||||
|
||||
config PROC_AVC
|
||||
bool "support (/proc/avc_msg)"
|
||||
default n
|
||||
help
|
||||
support logging audit avc message
|
||||
When PROC_AVC config is turned on, proc/avc_msg path is created and then,
|
||||
can use it to analyze the SEandroid denial.
|
||||
|
||||
config PROC_CHILDREN
|
||||
bool "Include /proc/<pid>/task/<tid>/children file"
|
||||
depends on PROC_FS
|
||||
|
@@ -34,4 +34,3 @@ proc-$(CONFIG_PROC_VMCORE) += vmcore.o
|
||||
proc-$(CONFIG_PRINTK) += kmsg.o
|
||||
proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
|
||||
proc-$(CONFIG_BOOT_CONFIG) += bootconfig.o
|
||||
proc-$(CONFIG_PROC_AVC) += proc_avc.o
|
||||
|
215
fs/proc/base.c
215
fs/proc/base.c
@@ -98,8 +98,6 @@
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/ksm.h>
|
||||
#include <linux/cpufreq_times.h>
|
||||
#include <linux/task_integrity.h>
|
||||
#include <linux/proca.h>
|
||||
#include <trace/events/oom.h>
|
||||
#include <trace/hooks/sched.h>
|
||||
#include "internal.h"
|
||||
@@ -107,10 +105,6 @@
|
||||
|
||||
#include "../../lib/kstrtox.h"
|
||||
|
||||
#ifdef CONFIG_IO_RECORD
|
||||
#include <linux/io_record.h>
|
||||
#endif
|
||||
|
||||
/* NOTE:
|
||||
* Implementing inode permission operations in /proc is almost
|
||||
* certainly an error. Permission checks need to happen during
|
||||
@@ -3182,207 +3176,6 @@ static const struct file_operations proc_setgroups_operations = {
|
||||
};
|
||||
#endif /* CONFIG_USER_NS */
|
||||
|
||||
#ifdef CONFIG_FIVE
|
||||
static int proc_integrity_value_read(struct seq_file *m,
|
||||
struct pid_namespace *ns, struct pid *pid,
|
||||
struct task_struct *task)
|
||||
{
|
||||
seq_printf(m, "%x\n", task_integrity_user_read(TASK_INTEGRITY(task)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_integrity_label_read(struct seq_file *m,
|
||||
struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
struct integrity_label *l;
|
||||
spin_lock(&TASK_INTEGRITY(task)->value_lock);
|
||||
l = TASK_INTEGRITY(task)->label;
|
||||
spin_unlock(&TASK_INTEGRITY(task)->value_lock);
|
||||
if (l) {
|
||||
size_t remaining_len;
|
||||
char *buffer = NULL;
|
||||
size_t data_len = l->len * 2;
|
||||
seq_printf(m, "%zu\n", data_len);
|
||||
remaining_len = seq_get_buf(m, &buffer);
|
||||
if (data_len && remaining_len > 1) {
|
||||
size_t size = min(data_len, remaining_len);
|
||||
bin2hex(buffer, l->data, size / 2);
|
||||
seq_commit(m, size);
|
||||
}
|
||||
} else {
|
||||
seq_printf(m, "%d\n", -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_integrity_reset_cause(struct seq_file *m,
|
||||
struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
if (TASK_INTEGRITY(task)->reset_cause)
|
||||
seq_printf(m, "%s\n", tint_reset_cause_to_string(
|
||||
TASK_INTEGRITY(task)->reset_cause));
|
||||
else
|
||||
seq_printf(m, "%s", "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_integrity_reset_file(struct seq_file *m,
|
||||
struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
char *pathname;
|
||||
if (!TASK_INTEGRITY(task)->reset_file) {
|
||||
seq_printf(m, "%s", "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
pathname = d_path(&TASK_INTEGRITY(task)->reset_file->f_path, tmp, PAGE_SIZE);
|
||||
if (IS_ERR(pathname))
|
||||
goto out;
|
||||
seq_printf(m, "%s\n", pathname);
|
||||
|
||||
out:
|
||||
free_page((unsigned long)tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROCA_DEBUG
|
||||
static int proc_get_proca_cert(struct seq_file *m,
|
||||
struct pid_namespace *ns, struct pid *pid,
|
||||
struct task_struct *task)
|
||||
{
|
||||
const char *cert;
|
||||
size_t cert_size;
|
||||
if (!proca_get_task_cert(task, &cert, &cert_size)) {
|
||||
size_t remaining_len;
|
||||
char *buffer = NULL;
|
||||
size_t data_len = cert_size * 2;
|
||||
seq_printf(m, "%zu\n", data_len);
|
||||
remaining_len = seq_get_buf(m, &buffer);
|
||||
if (data_len && remaining_len > 1) {
|
||||
size_t size = min(data_len, remaining_len);
|
||||
bin2hex(buffer, cert, size / 2);
|
||||
seq_commit(m, size);
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
} else {
|
||||
seq_printf(m, "%d\n", -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static const struct pid_entry integrity_dir_stuff[] = {
|
||||
ONE("value", S_IRUGO, proc_integrity_value_read),
|
||||
ONE("label", S_IRUGO, proc_integrity_label_read),
|
||||
ONE("reset_cause", S_IRUGO, proc_integrity_reset_cause),
|
||||
ONE("reset_file", S_IRUGO, proc_integrity_reset_file),
|
||||
#ifdef CONFIG_PROCA_DEBUG
|
||||
ONE("proca_certificate", S_IRUGO, proc_get_proca_cert),
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct dentry *proc_integrity_instantiate(struct dentry *dentry,
|
||||
struct task_struct *task, const void *ptr)
|
||||
{
|
||||
const struct pid_entry *p = ptr;
|
||||
struct inode *inode;
|
||||
struct proc_inode *ei;
|
||||
inode = proc_pid_make_inode(dentry->d_sb, task, p->mode);
|
||||
if (!inode)
|
||||
goto out;
|
||||
ei = PROC_I(inode);
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
set_nlink(inode, 2); /* Use getattr to fix if necessary */
|
||||
if (p->iop)
|
||||
inode->i_op = p->iop;
|
||||
if (p->fop)
|
||||
inode->i_fop = p->fop;
|
||||
ei->op = p->op;
|
||||
d_set_d_op(dentry, &pid_dentry_operations);
|
||||
return d_splice_alias(inode, dentry);
|
||||
out:
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
static struct dentry *proc_integrity_lookup_common(struct inode *dir,
|
||||
struct dentry *dentry, const struct pid_entry *ents,
|
||||
unsigned int nents)
|
||||
{
|
||||
struct dentry *error = ERR_PTR(-ENOENT);
|
||||
struct task_struct *task = get_proc_task(dir);
|
||||
const struct pid_entry *p, *last;
|
||||
if (!task)
|
||||
goto out_no_task;
|
||||
last = &ents[nents - 1];
|
||||
for (p = ents; p <= last; ++p) {
|
||||
if (p->len != dentry->d_name.len)
|
||||
continue;
|
||||
if (!memcmp(dentry->d_name.name, p->name, p->len))
|
||||
break;
|
||||
}
|
||||
if (p > last)
|
||||
goto out;
|
||||
error = proc_integrity_instantiate(dentry, task, p);
|
||||
out:
|
||||
put_task_struct(task);
|
||||
out_no_task:
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct dentry *proc_integrity_lookup(struct inode *dir,
|
||||
struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
return proc_integrity_lookup_common(dir, dentry,
|
||||
integrity_dir_stuff, ARRAY_SIZE(integrity_dir_stuff));
|
||||
}
|
||||
|
||||
static int proc_integrity_readdir_common(struct file *file,
|
||||
struct dir_context *ctx, const struct pid_entry *ents,
|
||||
unsigned int nents)
|
||||
{
|
||||
struct task_struct *task = get_proc_task(file_inode(file));
|
||||
const struct pid_entry *p;
|
||||
if (!task)
|
||||
return -ENOENT;
|
||||
if (!dir_emit_dots(file, ctx))
|
||||
goto out;
|
||||
if (ctx->pos >= nents + 2)
|
||||
goto out;
|
||||
for (p = ents + (ctx->pos - 2); p <= ents + nents - 1; ++p) {
|
||||
if (!proc_fill_cache(file, ctx, p->name, p->len,
|
||||
proc_integrity_instantiate, task, p))
|
||||
break;
|
||||
++(ctx->pos);
|
||||
}
|
||||
out:
|
||||
put_task_struct(task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_integrity_readdir(struct file *file, struct dir_context *ctx)
|
||||
{
|
||||
return proc_integrity_readdir_common(file, ctx, integrity_dir_stuff,
|
||||
ARRAY_SIZE(integrity_dir_stuff));
|
||||
}
|
||||
|
||||
static const struct inode_operations proc_integrity_inode_operations = {
|
||||
.lookup = proc_integrity_lookup,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_integrity_operations = {
|
||||
.read = generic_read_dir,
|
||||
.iterate_shared = proc_integrity_readdir,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
@@ -3487,10 +3280,6 @@ static const struct pid_entry tgid_base_stuff[] = {
|
||||
ONE("stat", S_IRUGO, proc_tgid_stat),
|
||||
ONE("statm", S_IRUGO, proc_pid_statm),
|
||||
REG("maps", S_IRUGO, proc_pid_maps_operations),
|
||||
#ifdef CONFIG_IO_RECORD
|
||||
REG("filemap_list", 0444, proc_pid_filemap_list_ops),
|
||||
REG("io_record_control", 0666, proc_pid_io_record_ops),
|
||||
#endif
|
||||
#ifdef CONFIG_NUMA
|
||||
REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
|
||||
#endif
|
||||
@@ -3573,10 +3362,6 @@ static const struct pid_entry tgid_base_stuff[] = {
|
||||
#ifdef CONFIG_SECCOMP_CACHE_DEBUG
|
||||
ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
|
||||
#endif
|
||||
#ifdef CONFIG_FIVE
|
||||
DIR("integrity", S_IRUGO|S_IXUGO, proc_integrity_inode_operations,
|
||||
proc_integrity_operations),
|
||||
#endif
|
||||
#ifdef CONFIG_KSM
|
||||
ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages),
|
||||
ONE("ksm_stat", S_IRUSR, proc_pid_ksm_stat),
|
||||
|
@@ -2072,123 +2072,3 @@ const struct file_operations proc_pid_numa_maps_operations = {
|
||||
};
|
||||
|
||||
#endif /* CONFIG_NUMA */
|
||||
|
||||
#ifdef CONFIG_IO_RECORD
|
||||
#include <linux/io_record.h>
|
||||
|
||||
struct proc_filemap_private {
|
||||
struct proc_maps_private maps_private;
|
||||
bool show_list;
|
||||
};
|
||||
|
||||
static atomic_t filemap_fd_opened = ATOMIC_INIT(0);
|
||||
|
||||
static int show_filemap(struct seq_file *m, void *v)
|
||||
{
|
||||
struct vm_area_struct *vma = v;
|
||||
struct file *file = vma->vm_file;
|
||||
struct proc_filemap_private *priv = m->private;
|
||||
char strbuf[MAX_FILEPATH_LEN];
|
||||
char *path;
|
||||
|
||||
if (!file || !priv->show_list)
|
||||
return 0;
|
||||
|
||||
path = d_path(&file->f_path, strbuf, MAX_FILEPATH_LEN);
|
||||
if (IS_ERR(path))
|
||||
return 0;
|
||||
|
||||
if (!strncmp(path, "/data", 5) || !strncmp(path, "/system", 7)) {
|
||||
seq_puts(m, path);
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations proc_pid_filemap_op = {
|
||||
.start = m_start,
|
||||
.next = m_next,
|
||||
.stop = m_stop,
|
||||
.show = show_filemap,
|
||||
};
|
||||
|
||||
static int pid_filemap_list_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct proc_filemap_private *priv = __seq_open_private(file,
|
||||
&proc_pid_filemap_op, sizeof(struct proc_filemap_private));
|
||||
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
if (atomic_inc_return(&filemap_fd_opened) > 1) {
|
||||
atomic_dec(&filemap_fd_opened);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->maps_private.inode = inode;
|
||||
priv->maps_private.mm = proc_mem_open(inode, PTRACE_MODE_READ);
|
||||
priv->show_list = true;
|
||||
if (IS_ERR(priv->maps_private.mm)) {
|
||||
atomic_dec(&filemap_fd_opened);
|
||||
seq_release_private(inode, file);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_filemap_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct seq_file *seq = file->private_data;
|
||||
struct proc_filemap_private *priv = seq->private;
|
||||
|
||||
if (priv->maps_private.mm)
|
||||
mmdrop(priv->maps_private.mm);
|
||||
|
||||
atomic_dec(&filemap_fd_opened);
|
||||
return seq_release_private(inode, file);
|
||||
}
|
||||
|
||||
const struct file_operations proc_pid_filemap_list_ops = {
|
||||
.open = pid_filemap_list_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = proc_filemap_release,
|
||||
};
|
||||
|
||||
static ssize_t pid_io_record_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return io_record_read(buf, count, ppos);
|
||||
}
|
||||
|
||||
static ssize_t pid_io_record_write(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct task_struct *task;
|
||||
char buffer[PROC_NUMBUF];
|
||||
int rv, type;
|
||||
bool ret;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
count = min_t(size_t, count, sizeof(buffer) - 1);
|
||||
if (copy_from_user(buffer, buf, count))
|
||||
return -EFAULT;
|
||||
rv = kstrtoint(strstrip(buffer), 10, &type);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
task = get_proc_task(file_inode(file));
|
||||
if (!task)
|
||||
return -EFAULT;
|
||||
|
||||
ret = io_record_write(task, type);
|
||||
put_task_struct(task);
|
||||
|
||||
return ret ? count : -EINVAL;
|
||||
}
|
||||
|
||||
const struct file_operations proc_pid_io_record_ops = {
|
||||
.read = pid_io_record_read,
|
||||
.write = pid_io_record_write,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user