Re: PATCH: signals security

Alexander Kjeldaas (astor@guardian.no)
Fri, 22 May 1998 01:06:10 +0200


--TB36FDmn/VVEgNH/
Content-Type: text/plain; charset=us-ascii

On Fri, May 22, 1998 at 12:48:23AM +0200, Rik van Riel wrote:
> On Fri, 22 May 1998, Alexander Kjeldaas wrote:
> > On Thu, May 21, 1998 at 07:49:37PM +0200, Rik van Riel wrote:
> > >
> > > This would indeed be the 'perfect' solution.
> >
> > Attached is a patch implementing a cap_used set.
>
> OK, I'll start adapting the iopl() and ioperm() functions
> to set the CAP_RAW_IO in cap_used, so we can know when a
> process has actually used this function.
>

You don't have to do that. With the patch, when iopl and ioperm calls
capable(CAP_RAW_IO), the bit will be set automatically.

However, cap_used doesn't really do what you want. What you want is to
know if you can reliably kill a process. You can kill it if (in this
context) a process has not used CAP_RAW_IO _and_ don't have any open
file descriptors inherited from a parent process which used
CAP_RAW_IO.

cap_used as I hacked up doesn't take care of the last case. However,
if we don't clear cap_used during fork, the process tree started by X
will be permanently "dirtied". I think this is ok for your use.

It all depends on what you want to know about a process.

I've attached a new patch which has a cap_used as well as cap_dirty
capabilities. cap_dirty should be what you check against since it will
be inherited by fork().

> Then we just hope for the other architectures to set this
> bit too. (what do we do about 68k? they just mmap() the
> frame buffer, so maybe it's safe to kill the X server on
> that architecture?)
>

When the device is open()ed, the kernel should check whether the
process has the CAP_RAW_IO capability. If it doesn't, it's a bug
(unless the frame-buffer isn't "raw" access to hardware on m68k in
which case it would be ok to kill the X-server).

astor

-- 
 Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway
 http://www.guardian.no/

--TB36FDmn/VVEgNH/ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cap-used2.diff"

diff -urN linux/fs/proc/array.c l/fs/proc/array.c --- linux/fs/proc/array.c Wed May 6 20:01:45 1998 +++ l/fs/proc/array.c Fri May 22 01:00:26 1998 @@ -768,10 +768,14 @@ { return buffer + sprintf(buffer, "CapInh:\t%016x\n" "CapPrm:\t%016x\n" - "CapEff:\t%016x\n", + "CapEff:\t%016x\n" + "CapUsd:\t%016x\n" + "CapDrt:\t%016x\n", p->cap_inheritable.cap, p->cap_permitted.cap, - p->cap_effective.cap); + p->cap_effective.cap, + p->cap_used.cap, + p->cap_dirty.cap); } diff -urN linux/include/linux/sched.h l/include/linux/sched.h --- linux/include/linux/sched.h Thu May 21 23:20:19 1998 +++ l/include/linux/sched.h Fri May 22 01:01:57 1998 @@ -261,7 +261,8 @@ gid_t gid,egid,sgid,fsgid; int ngroups; gid_t groups[NGROUPS]; - kernel_cap_t cap_effective, cap_inheritable, cap_permitted; + kernel_cap_t cap_effective, cap_inheritable, cap_permitted, + cap_used, cap_dirty; /* limits */ struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; @@ -355,6 +356,7 @@ /* uid etc */ 0,0,0,0,0,0,0,0, \ /* suppl grps*/ 0, {0,}, \ /* caps */ CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \ + CAP_EMPTY_SET, CAP_EMPTY_SET, \ /* rlimits */ INIT_RLIMITS, \ /* math */ 0, \ /* comm */ "swapper", \ @@ -572,6 +574,8 @@ #endif { current->flags |= PF_SUPERPRIV; + current->cap_used.cap |= CAP_TO_MASK(cap); + current->cap_dirty.cap |= CAP_TO_MASK(cap); return 1; } return 0; diff -urN linux/kernel/fork.c l/kernel/fork.c --- linux/kernel/fork.c Wed May 6 23:42:54 1998 +++ l/kernel/fork.c Thu May 21 23:27:53 1998 @@ -506,6 +506,7 @@ p->tty_old_pgrp = 0; p->times.tms_utime = p->times.tms_stime = 0; p->times.tms_cutime = p->times.tms_cstime = 0; + cap_clear(p->cap_used); #ifdef __SMP__ { int i;

--TB36FDmn/VVEgNH/--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu