active-standby: add cmdline into /proc/net/
[linux-2.6.git] / fs / proc / base.c
index 7d6ad98..68375eb 100644 (file)
@@ -45,6 +45,8 @@
  *
  *  Paul Mundt <paul.mundt@nokia.com>:
  *  Overall revision about smaps.
+ *
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
  */
 
 #include <asm/uaccess.h>
@@ -137,6 +139,12 @@ struct pid_entry {
 
 static int proc_fd_permission(struct inode *inode, int mask);
 
+/* ANDROID is for special files in /proc. */
+#define ANDROID(NAME, MODE, OTYPE)                     \
+       NOD(NAME, (S_IFREG|(MODE)),                     \
+               &proc_##OTYPE##_inode_operations,       \
+               &proc_##OTYPE##_operations, {})
+
 /*
  * Count the number of hardlinks for the pid_entry table, excluding the .
  * and .. links.
@@ -203,7 +211,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
        return mm_access(task, PTRACE_MODE_READ);
 }
 
-static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+static int proc_pid_cmdline(struct task_struct *task, char *buffer)
 {
        int res = 0;
        unsigned int len;
@@ -969,6 +977,35 @@ out:
        return err < 0 ? err : count;
 }
 
+static int oom_adjust_permission(struct inode *inode, int mask)
+{
+       uid_t uid;
+       struct task_struct *p;
+
+       p = get_proc_task(inode);
+       if(p) {
+               uid = task_uid(p);
+               put_task_struct(p);
+       }
+
+       /*
+        * System Server (uid == 1000) is granted access to oom_adj of all 
+        * android applications (uid > 10000) as and services (uid >= 1000)
+        */
+       if (p && (current_fsuid() == 1000) && (uid >= 1000)) {
+               if (inode->i_mode >> 6 & mask) {
+                       return 0;
+               }
+       }
+
+       /* Fall back to default. */
+       return generic_permission(inode, mask);
+}
+
+static const struct inode_operations proc_oom_adjust_inode_operations = {
+       .permission     = oom_adjust_permission,
+};
+
 static const struct file_operations proc_oom_adjust_operations = {
        .read           = oom_adjust_read,
        .write          = oom_adjust_write,
@@ -1803,7 +1840,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
                        rcu_read_lock();
                        file = fcheck_files(files, fd);
                        if (file) {
-                               unsigned i_mode, f_mode = file->f_mode;
+                               unsigned f_mode = file->f_mode;
 
                                rcu_read_unlock();
                                put_files_struct(files);
@@ -1819,12 +1856,14 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
                                        inode->i_gid = 0;
                                }
 
-                               i_mode = S_IFLNK;
-                               if (f_mode & FMODE_READ)
-                                       i_mode |= S_IRUSR | S_IXUSR;
-                               if (f_mode & FMODE_WRITE)
-                                       i_mode |= S_IWUSR | S_IXUSR;
-                               inode->i_mode = i_mode;
+                               if (S_ISLNK(inode->i_mode)) {
+                                       unsigned i_mode = S_IFLNK;
+                                       if (f_mode & FMODE_READ)
+                                               i_mode |= S_IRUSR | S_IXUSR;
+                                       if (f_mode & FMODE_WRITE)
+                                               i_mode |= S_IWUSR | S_IXUSR;
+                                       inode->i_mode = i_mode;
+                               }
 
                                security_task_to_inode(task, inode);
                                put_task_struct(task);
@@ -1859,6 +1898,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
        ei = PROC_I(inode);
        ei->fd = fd;
 
+       inode->i_mode = S_IFLNK;
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
        ei->op.proc_get_link = proc_fd_link;
@@ -2162,16 +2202,16 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
                goto out;
 
        result = ERR_PTR(-EACCES);
-       if (lock_trace(task))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ))
                goto out_put_task;
 
        result = ERR_PTR(-ENOENT);
        if (dname_to_vma_addr(dentry, &vm_start, &vm_end))
-               goto out_unlock;
+               goto out_put_task;
 
        mm = get_task_mm(task);
        if (!mm)
-               goto out_unlock;
+               goto out_put_task;
 
        down_read(&mm->mmap_sem);
        vma = find_exact_vma(mm, vm_start, vm_end);
@@ -2183,8 +2223,6 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
 out_no_vma:
        up_read(&mm->mmap_sem);
        mmput(mm);
-out_unlock:
-       unlock_trace(task);
 out_put_task:
        put_task_struct(task);
 out:
@@ -2218,7 +2256,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
                goto out;
 
        ret = -EACCES;
-       if (lock_trace(task))
+       if (!ptrace_may_access(task, PTRACE_MODE_READ))
                goto out_put_task;
 
        ret = 0;
@@ -2226,12 +2264,12 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
        case 0:
                ino = inode->i_ino;
                if (filldir(dirent, ".", 1, 0, ino, DT_DIR) < 0)
-                       goto out_unlock;
+                       goto out_put_task;
                filp->f_pos++;
        case 1:
                ino = parent_ino(dentry);
                if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
-                       goto out_unlock;
+                       goto out_put_task;
                filp->f_pos++;
        default:
        {
@@ -2242,7 +2280,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
                mm = get_task_mm(task);
                if (!mm)
-                       goto out_unlock;
+                       goto out_put_task;
                down_read(&mm->mmap_sem);
 
                nr_files = 0;
@@ -2272,7 +2310,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
                                        flex_array_free(fa);
                                up_read(&mm->mmap_sem);
                                mmput(mm);
-                               goto out_unlock;
+                               goto out_put_task;
                        }
                        for (i = 0, vma = mm->mmap, pos = 2; vma;
                                        vma = vma->vm_next) {
@@ -2317,8 +2355,6 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
        }
        }
 
-out_unlock:
-       unlock_trace(task);
 out_put_task:
        put_task_struct(task);
 out:
@@ -3012,7 +3048,7 @@ static const struct pid_entry tgid_base_stuff[] = {
        REG("cgroup",  S_IRUGO, proc_cgroup_operations),
 #endif
        INF("oom_score",  S_IRUGO, proc_oom_score),
-       REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
+       ANDROID("oom_adj",S_IRUGO|S_IWUSR, oom_adjust),
        REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
 #ifdef CONFIG_AUDITSYSCALL
        REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),