rpms/kernel/devel kernel-2.6.spec, 1.2531, 1.2532 linux-2.6-utrace.patch, 1.14, 1.15
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Tue Aug 8 20:22:51 UTC 2006
Author: roland
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv28430
Modified Files:
kernel-2.6.spec linux-2.6-utrace.patch
Log Message:
Fix utrace/ptrace interactions with SELinux.
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2531
retrieving revision 1.2532
diff -u -r1.2531 -r1.2532
--- kernel-2.6.spec 8 Aug 2006 19:28:09 -0000 1.2531
+++ kernel-2.6.spec 8 Aug 2006 20:22:48 -0000 1.2532
@@ -1693,6 +1693,9 @@
%endif
%changelog
+* Tue Aug 8 2006 Roland McGrath <roland at redhat.com>
+- Fix utrace/ptrace interactions with SELinux.
+
* Tue Aug 8 2006 Dave Jones <davej at redhat.com>
- Pull post-rc4 fixes from GregKH's git tree.
linux-2.6-utrace.patch:
Documentation/utrace.txt | 455 +++++++++
arch/alpha/kernel/asm-offsets.c | 2
arch/alpha/kernel/entry.S | 4
arch/arm/kernel/ptrace.c | 36
arch/arm26/kernel/ptrace.c | 32
arch/frv/kernel/ptrace.c | 15
arch/i386/kernel/entry.S | 7
arch/i386/kernel/i387.c | 143 +-
arch/i386/kernel/process.c | 3
arch/i386/kernel/ptrace.c | 839 +++++++++--------
arch/i386/kernel/signal.c | 39
arch/i386/kernel/vm86.c | 7
arch/ia64/ia32/ia32_entry.S | 2
arch/ia64/ia32/sys_ia32.c | 23
arch/ia64/kernel/asm-offsets.c | 2
arch/ia64/kernel/fsys.S | 16
arch/ia64/kernel/mca.c | 2
arch/ia64/kernel/ptrace.c | 41
arch/ia64/kernel/signal.c | 4
arch/mips/kernel/ptrace.c | 21
arch/mips/kernel/sysirix.c | 2
arch/powerpc/kernel/Makefile | 4
arch/powerpc/kernel/asm-offsets.c | 2
arch/powerpc/kernel/process.c | 5
arch/powerpc/kernel/ptrace-common.h | 161 ---
arch/powerpc/kernel/ptrace.c | 785 +++++++---------
arch/powerpc/kernel/ptrace32.c | 436 --------
arch/powerpc/kernel/signal_32.c | 56 +
arch/powerpc/kernel/signal_64.c | 4
arch/powerpc/kernel/sys_ppc32.c | 5
arch/powerpc/lib/sstep.c | 3
arch/powerpc/platforms/cell/spufs/run.c | 2
arch/ppc/kernel/asm-offsets.c | 2
arch/s390/kernel/compat_linux.c | 3
arch/s390/kernel/compat_signal.c | 5
arch/s390/kernel/process.c | 3
arch/s390/kernel/ptrace.c | 553 ++++++++++-
arch/s390/kernel/signal.c | 4
arch/s390/kernel/traps.c | 6
arch/sparc64/kernel/entry.S | 6
arch/sparc64/kernel/process.c | 3
arch/sparc64/kernel/ptrace.c | 653 +++++++++++--
arch/sparc64/kernel/signal.c | 2
arch/sparc64/kernel/signal32.c | 2
arch/sparc64/kernel/sys_sparc32.c | 3
arch/sparc64/kernel/systbls.S | 4
arch/x86_64/ia32/fpu32.c | 92 +
arch/x86_64/ia32/ia32_aout.c | 6
arch/x86_64/ia32/ia32_signal.c | 8
arch/x86_64/ia32/ia32entry.S | 2
arch/x86_64/ia32/ptrace32.c | 688 +++++++++-----
arch/x86_64/ia32/sys_ia32.c | 5
arch/x86_64/kernel/process.c | 5
arch/x86_64/kernel/ptrace.c | 619 +++++++-----
arch/x86_64/kernel/signal.c | 30
arch/x86_64/kernel/traps.c | 8
arch/x86_64/mm/fault.c | 4
drivers/connector/cn_proc.c | 4
fs/binfmt_aout.c | 6
fs/binfmt_elf.c | 6
fs/binfmt_elf_fdpic.c | 7
fs/binfmt_flat.c | 3
fs/binfmt_som.c | 2
fs/exec.c | 11
fs/proc/array.c | 14
fs/proc/base.c | 17
include/asm-i386/i387.h | 13
include/asm-i386/signal.h | 4
include/asm-i386/thread_info.h | 7
include/asm-i386/tracehook.h | 74 +
include/asm-ia64/tracehook.h | 67 +
include/asm-powerpc/tracehook.h | 303 ++++++
include/asm-s390/tracehook.h | 105 ++
include/asm-sparc64/tracehook.h | 44
include/asm-x86_64/fpu32.h | 3
include/asm-x86_64/thread_info.h | 2
include/asm-x86_64/tracehook.h | 106 ++
include/linux/init_task.h | 3
include/linux/ptrace.h | 86 -
include/linux/sched.h | 25
include/linux/tracehook.h | 641 +++++++++++++
include/linux/utrace.h | 481 +++++++++
init/Kconfig | 29
kernel/Makefile | 1
kernel/exit.c | 259 +----
kernel/fork.c | 62 -
kernel/ptrace.c | 1563 +++++++++++++++++++++++++-------
kernel/signal.c | 211 ----
kernel/sys.c | 2
kernel/timer.c | 6
kernel/utrace.c | 1526 +++++++++++++++++++++++++++++++
security/selinux/hooks.c | 54 -
security/selinux/include/objsec.h | 1
93 files changed, 8297 insertions(+), 3325 deletions(-)
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- linux-2.6-utrace.patch 7 Aug 2006 19:07:58 -0000 1.14
+++ linux-2.6-utrace.patch 8 Aug 2006 20:22:48 -0000 1.15
@@ -62,7 +62,7 @@
fs/binfmt_flat.c | 3
fs/binfmt_som.c | 2
fs/exec.c | 11
- fs/proc/array.c | 7
+ fs/proc/array.c | 14
fs/proc/base.c | 17
include/asm-i386/i387.h | 13
include/asm-i386/signal.h | 4
@@ -78,19 +78,20 @@
include/linux/init_task.h | 3
include/linux/ptrace.h | 86 +-
include/linux/sched.h | 25
- include/linux/tracehook.h | 644 +++++++++++++
- include/linux/utrace.h | 470 +++++++++
+ include/linux/tracehook.h | 641 +++++++++++++
+ include/linux/utrace.h | 481 ++++++++++
init/Kconfig | 29 +
kernel/Makefile | 1
kernel/exit.c | 259 +----
kernel/fork.c | 62 -
- kernel/ptrace.c | 1565 ++++++++++++++++++++++++-------
+ kernel/ptrace.c | 1563 ++++++++++++++++++++++++-------
kernel/signal.c | 211 +---
kernel/sys.c | 2
kernel/timer.c | 6
- kernel/utrace.c | 1520 ++++++++++++++++++++++++++++++
- security/selinux/hooks.c | 6
- 92 files changed, 8251 insertions(+), 3305 deletions(-)
+ kernel/utrace.c | 1526 ++++++++++++++++++++++++++++++
+ security/selinux/hooks.c | 54 +
+ security/selinux/include/objsec.h | 1
+ 93 files changed, 8298 insertions(+), 3326 deletions(-)
create mode 100644 Documentation/utrace.txt
delete arch/powerpc/kernel/ptrace-common.h
delete arch/powerpc/kernel/ptrace32.c
@@ -1007,7 +1008,7 @@
extern int send_sig(int, struct task_struct *, int);
--- linux-2.6/include/linux/utrace.h.utrace-ptrace-compat
+++ linux-2.6/include/linux/utrace.h
-@@ -0,0 +1,470 @@
+@@ -0,0 +1,481 @@
+/*
+ * User Debugging Data & Event Rendezvous
+ *
@@ -1382,11 +1383,22 @@
+ struct task_struct *target);
+
+ /*
-+ * Return the value to display after "TracerPid:" in /proc/PID/status.
-+ * If this engine returns zero, another engine may supply the value.
++ * Return the task_struct for the task using ptrace on this one, or
++ * NULL. Always called with rcu_read_lock held to keep the
++ * returned struct alive.
++ *
++ * At exec time, this may be called with task_lock(target) still
++ * held from when unsafe_exec was just called. In that case it
++ * must give results consistent with those unsafe_exec results,
++ * i.e. non-NULL if any LSM_UNSAFE_PTRACE_* bits were set.
++ *
++ * The value is also used to display after "TracerPid:" in
++ * /proc/PID/status, where it is called with only rcu_read_lock held.
++ *
++ * If this engine returns NULL, another engine may supply the result.
+ */
-+ pid_t (*tracer_pid)(struct utrace_attached_engine *engine,
-+ struct task_struct *target);
++ struct task_struct *(*tracer_task)(struct utrace_attached_engine *,
++ struct task_struct *target);
+};
+
+
@@ -1471,7 +1483,7 @@
+int utrace_report_jctl(int type);
+void utrace_report_exec(struct linux_binprm *bprm, struct pt_regs *regs);
+void utrace_report_syscall(struct pt_regs *regs, int is_exit);
-+pid_t utrace_tracer_pid(struct task_struct *);
++struct task_struct *utrace_tracer_task(struct task_struct *);
+int utrace_allow_access_process_vm(struct task_struct *);
+int utrace_unsafe_exec(struct task_struct *);
+void utrace_signal_handler_singlestep(struct task_struct *, struct pt_regs *);
@@ -1592,7 +1604,7 @@
.sibling = LIST_HEAD_INIT(tsk.sibling), \
--- linux-2.6/include/linux/tracehook.h.utrace-ptrace-compat
+++ linux-2.6/include/linux/tracehook.h
-@@ -0,0 +1,644 @@
+@@ -0,0 +1,641 @@
+/*
+ * Tracing hooks
+ *
@@ -1842,18 +1854,6 @@
+#include <linux/utrace.h>
+#endif
+
-+/*
-+ * Return the value to display after "TracerPid:" in /proc/PID/status.
-+ * Called without locks.
-+ */
-+static inline pid_t tracehook_tracer_pid(struct task_struct *p)
-+{
-+#ifdef CONFIG_UTRACE
-+ if (p->utrace_flags)
-+ return utrace_tracer_pid(p);
-+#endif
-+ return 0;
-+}
+
+/*
+ * Called in copy_process when setting up the copied task_struct,
@@ -2073,13 +2073,22 @@
+}
+
+/*
-+ * Return nonzero if the task is being traced so security checks should apply.
-+ * Called with task_lock(tsk) held.
++ * Return the task_struct for the task using ptrace on this one, or NULL.
++ * Must be called with rcu_read_lock held to keep the returned struct alive.
++ *
++ * At exec time, this may be called with task_lock(p) still held from when
++ * tracehook_unsafe_exec was just called.
++ *
++ * The value is also used to display after "TracerPid:" in /proc/PID/status,
++ * where it is called with only rcu_read_lock held.
+ */
-+static inline int tracehook_security_ptrace(struct task_struct *tsk)
++static inline struct task_struct *tracehook_tracer_task(struct task_struct *p)
+{
-+ return 0;
-+ // return (p->ptrace & PT_PTRACED);
++#ifdef CONFIG_UTRACE
++ if (p->utrace_flags)
++ return utrace_tracer_task(p);
++#endif
++ return NULL;
+}
+
+/*
@@ -2695,6 +2704,16 @@
+value. It says to push the signal back on the thread's queue, with
+the signal number and details possibly changed in info. When the
+thread is allowed to resume, it will dequeue and report it again.
+--- linux-2.6/security/selinux/include/objsec.h.utrace-ptrace-compat
++++ linux-2.6/security/selinux/include/objsec.h
+@@ -34,7 +34,6 @@ struct task_security_struct {
+ u32 create_sid; /* fscreate SID */
+ u32 keycreate_sid; /* keycreate SID */
+ u32 sockcreate_sid; /* fscreate SID */
+- u32 ptrace_sid; /* SID of ptrace parent */
+ };
+
+ struct inode_security_struct {
--- linux-2.6/security/selinux/hooks.c.utrace-ptrace-compat
+++ linux-2.6/security/selinux/hooks.c
@@ -21,7 +21,7 @@
@@ -2706,24 +2725,115 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/security.h>
-@@ -1397,7 +1397,7 @@ static int selinux_ptrace(struct task_st
+@@ -159,7 +159,7 @@ static int task_alloc_security(struct ta
+ return -ENOMEM;
- rc = task_has_perm(parent, child, PROCESS__PTRACE);
- /* Save the SID of the tracing process for later use in apply_creds. */
+ tsec->task = task;
+- tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
++ tsec->osid = tsec->sid = SECINITSID_UNLABELED;
+ task->security = tsec;
+
+ return 0;
+@@ -1387,19 +1387,13 @@ static int inode_security_set_sid(struct
+
+ static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
+ {
+- struct task_security_struct *psec = parent->security;
+- struct task_security_struct *csec = child->security;
+ int rc;
+
+ rc = secondary_ops->ptrace(parent,child);
+ if (rc)
+ return rc;
+
+- rc = task_has_perm(parent, child, PROCESS__PTRACE);
+- /* Save the SID of the tracing process for later use in apply_creds. */
- if (!(child->ptrace & PT_PTRACED) && !rc)
-+ if (/* XXX !(child->ptrace & PT_PTRACED) && */ !rc)
- csec->ptrace_sid = psec->sid;
- return rc;
+- csec->ptrace_sid = psec->sid;
+- return rc;
++ return task_has_perm(parent, child, PROCESS__PTRACE);
+ }
+
+ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
+@@ -1821,12 +1815,24 @@ static void selinux_bprm_apply_creds(str
+ /* Check for ptracing, and update the task SID if ok.
+ Otherwise, leave SID unchanged and kill. */
+ if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
+- rc = avc_has_perm(tsec->ptrace_sid, sid,
+- SECCLASS_PROCESS, PROCESS__PTRACE,
+- NULL);
+- if (rc) {
+- bsec->unsafe = 1;
+- return;
++ struct task_struct *t;
++
++ rcu_read_lock();
++ t = tracehook_tracer_task(current);
++ if (unlikely(t == NULL))
++ rcu_read_unlock();
++ else {
++ struct task_security_struct *sec = t->security;
++ u32 ptsid = sec->sid;
++ rcu_read_unlock();
++
++ rc = avc_has_perm(ptsid, sid,
++ SECCLASS_PROCESS,
++ PROCESS__PTRACE, NULL);
++ if (rc) {
++ bsec->unsafe = 1;
++ return;
++ }
+ }
+ }
+ tsec->sid = sid;
+@@ -2684,11 +2690,6 @@ static int selinux_task_alloc_security(s
+ tsec2->keycreate_sid = tsec1->keycreate_sid;
+ tsec2->sockcreate_sid = tsec1->sockcreate_sid;
+
+- /* Retain ptracer SID across fork, if any.
+- This will be reset by the ptrace hook upon any
+- subsequent ptrace_attach operations. */
+- tsec2->ptrace_sid = tsec1->ptrace_sid;
+-
+ return 0;
}
-@@ -4381,7 +4381,7 @@ static int selinux_setprocattr(struct ta
+
+@@ -4293,6 +4294,7 @@ static int selinux_setprocattr(struct ta
+ char *name, void *value, size_t size)
+ {
+ struct task_security_struct *tsec;
++ struct task_struct *tracer;
+ u32 sid = 0;
+ int error;
+ char *str = value;
+@@ -4381,18 +4383,24 @@ static int selinux_setprocattr(struct ta
/* Check for ptracing, and update the task SID if ok.
Otherwise, leave SID unchanged and fail. */
task_lock(p);
- if (p->ptrace & PT_PTRACED) {
-+ if (tracehook_security_ptrace(p)) {
- error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
+- error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
++ rcu_read_lock();
++ tracer = tracehook_tracer_task(p);
++ if (tracer != NULL) {
++ struct task_security_struct *ptsec = tracer->security;
++ u32 ptsid = ptsec->sid;
++ rcu_read_unlock();
++ error = avc_has_perm_noaudit(ptsid, sid,
SECCLASS_PROCESS,
PROCESS__PTRACE, &avd);
+ if (!error)
+ tsec->sid = sid;
+ task_unlock(p);
+- avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS,
++ avc_audit(ptsid, sid, SECCLASS_PROCESS,
+ PROCESS__PTRACE, &avd, error, NULL);
+ if (error)
+ return error;
+ } else {
++ rcu_read_unlock();
+ tsec->sid = sid;
+ task_unlock(p);
+ }
--- linux-2.6/kernel/fork.c.utrace-ptrace-compat
+++ linux-2.6/kernel/fork.c
@@ -36,7 +36,7 @@
@@ -3209,7 +3319,7 @@
EXPORT_SYMBOL(sigprocmask);
--- linux-2.6/kernel/utrace.c.utrace-ptrace-compat
+++ linux-2.6/kernel/utrace.c
-@@ -0,0 +1,1520 @@
+@@ -0,0 +1,1526 @@
+#include <linux/utrace.h>
+#include <linux/tracehook.h>
+#include <linux/err.h>
@@ -4646,16 +4756,23 @@
+
+
+/*
-+ * Return the value to display after "TracerPid:" in /proc/PID/status.
-+ * Called without locks.
++ * Return the task_struct for the task using ptrace on this one, or NULL.
++ * Must be called with rcu_read_lock held to keep the returned struct alive.
++ *
++ * At exec time, this may be called with task_lock(p) still held from when
++ * tracehook_unsafe_exec was just called. In that case it must give
++ * results consistent with those unsafe_exec results, i.e. non-NULL if
++ * any LSM_UNSAFE_PTRACE_* bits were set.
++ *
++ * The value is also used to display after "TracerPid:" in /proc/PID/status,
++ * where it is called with only rcu_read_lock held.
+ */
-+pid_t
-+utrace_tracer_pid(struct task_struct *target)
++struct task_struct *
++utrace_tracer_task(struct task_struct *target)
+{
+ struct utrace *utrace;
-+ pid_t pid = 0;
++ struct task_struct *tracer = NULL;
+
-+ rcu_read_lock();
+ utrace = rcu_dereference(target->utrace);
+ if (utrace != NULL) {
+ struct list_head *pos, *next;
@@ -4665,16 +4782,15 @@
+ engine = list_entry(pos, struct utrace_attached_engine,
+ entry);
+ ops = rcu_dereference(engine->ops);
-+ if (ops->tracer_pid) {
-+ pid = (*ops->tracer_pid)(engine, target);
-+ if (pid)
++ if (ops->tracer_task) {
++ tracer = (*ops->tracer_task)(engine, target);
++ if (tracer != NULL)
+ break;
+ }
+ }
+ }
-+ rcu_read_unlock();
+
-+ return pid;
++ return tracer;
+}
+
+int
@@ -5485,7 +5601,7 @@
/*
* Access another process' address space.
* Source/target buffer must be kernel space,
-@@ -295,249 +125,1306 @@ int access_process_vm(struct task_struct
+@@ -295,249 +125,1304 @@ int access_process_vm(struct task_struct
return buf - old_buf;
}
@@ -5690,7 +5806,9 @@
+ retval = -EPERM;
+ }
+ else {
++ task_lock(current);
+ retval = security_ptrace(current->parent, current);
++ task_unlock(current);
+ if (!retval)
+ retval = ptrace_setup(current, engine,
+ current->parent, 0, 0);
@@ -5759,7 +5877,7 @@
+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
+ /*
+ * Clearing ->data before detach makes sure an unrelated task
-+ * calling into ptrace_tracer_pid won't try to touch stale state.
++ * calling into ptrace_tracer_task won't try to touch stale state.
+ */
+ rcu_assign_pointer(engine->data, 0UL);
+ utrace_detach(task, engine);
@@ -6892,24 +7010,20 @@
+ return unsafe;
+}
+
-+static pid_t
-+ptrace_tracer_pid(struct utrace_attached_engine *engine,
-+ struct task_struct *target)
++static struct task_struct *
++ptrace_tracer_task(struct utrace_attached_engine *engine,
++ struct task_struct *target)
+{
+ struct ptrace_state *state;
-+ pid_t pid;
+
+ /*
+ * This call is not necessarily made by the target task,
+ * so ptrace might be getting detached while we run here.
+ * The state pointer will be NULL if that happens.
+ */
-+ rcu_read_lock();
+ state = rcu_dereference((struct ptrace_state *) engine->data);
-+ pid = state == NULL ? 0 : state->parent->pid;
-+ rcu_read_unlock();
+
-+ return pid;
++ return state == NULL ? NULL : state->parent;
+}
+
+static int
@@ -6949,7 +7063,7 @@
+ .report_exit = ptrace_report_exit,
+ .report_death = ptrace_report_death,
+ .unsafe_exec = ptrace_unsafe_exec,
-+ .tracer_pid = ptrace_tracer_pid,
++ .tracer_task = ptrace_tracer_task,
+ .allow_access_process_vm = ptrace_allow_access_process_vm,
+};
+
@@ -7055,18 +7169,36 @@
#include <linux/rcupdate.h>
#include <linux/delayacct.h>
-@@ -175,8 +176,8 @@ static inline char * task_state(struct t
+@@ -158,10 +159,17 @@ static inline const char * get_task_stat
+
+ static inline char * task_state(struct task_struct *p, char *buffer)
+ {
++ struct task_struct *tracer;
++ pid_t tracer_pid;
+ struct group_info *group_info;
+ int g;
+ struct fdtable *fdt = NULL;
+
++ rcu_read_lock();
++ tracer = tracehook_tracer_task(p);
++ tracer_pid = tracer == NULL ? 0 : tracer->pid;
++ rcu_read_unlock();
++
+ read_lock(&tasklist_lock);
+ buffer += sprintf(buffer,
+ "State:\t%s\n"
+@@ -175,8 +183,8 @@ static inline char * task_state(struct t
get_task_state(p),
(p->sleep_avg/1024)*100/(1020000000/1024),
p->tgid,
- p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
- pid_alive(p) && p->ptrace ? p->parent->pid : 0,
+ p->pid, pid_alive(p) ? p->group_leader->parent->tgid : 0,
-+ tracehook_tracer_pid(p),
++ tracer_pid,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
read_unlock(&tasklist_lock);
-@@ -386,7 +387,7 @@ static int do_task_stat(struct task_stru
+@@ -386,7 +394,7 @@ static int do_task_stat(struct task_stru
stime = cputime_add(stime, task->signal->stime);
}
}
More information about the fedora-cvs-commits
mailing list