lkml.org 
[lkml]   [1998]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectsuser() -> capable() for linux/*
This patch changes all suser() to capable() not in the directories
handled by the other patches. The patch also includes the following
things.

* Init is started without CAP_SETPCAP in inheritable and effective
capability set. This means that we don't _by default_ make root any
more powerful than it already is under compatibility mode.

* set*uid() compatibility is handled.

It does not include the system calls to set/get capabilities and
emulate securelevel.

astor

--
Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway
http://www.guardian.no/
diff -urN /tmp/l97/arch/alpha/kernel/bios32.c lp97/arch/alpha/kernel/bios32.c
--- /tmp/l97/arch/alpha/kernel/bios32.c Fri Apr 10 22:44:09 1998
+++ lp97/arch/alpha/kernel/bios32.c Thu Apr 23 01:25:45 1998
@@ -2041,7 +2041,7 @@
unsigned int uint;
long err = 0;

- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;

lock_kernel();
@@ -2082,7 +2082,7 @@
unsigned int uint;
long err = 0;

- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;

lock_kernel();
diff -urN /tmp/l97/arch/alpha/kernel/ptrace.c lp97/arch/alpha/kernel/ptrace.c
--- /tmp/l97/arch/alpha/kernel/ptrace.c Sun Nov 30 19:59:02 1997
+++ lp97/arch/alpha/kernel/ptrace.c Thu Apr 23 01:35:16 1998
@@ -506,7 +506,7 @@
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
- (current->gid != child->gid)) && !suser())
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
diff -urN /tmp/l97/arch/arm/kernel/ioport.c lp97/arch/arm/kernel/ioport.c
--- /tmp/l97/arch/arm/kernel/ioport.c Wed Jan 21 01:39:41 1998
+++ lp97/arch/arm/kernel/ioport.c Thu Apr 23 01:38:08 1998
@@ -58,7 +58,7 @@
if (from + num > IO_BITMAP_SIZE*32)
return -EINVAL;
#endif
- if (!suser())
+ if (!capable(CAP_SYS_RAWIO))
return -EPERM;

#ifdef IODEBUG
@@ -91,7 +91,7 @@

if (level > 3)
return -EINVAL;
- if (!suser())
+ if (!capable(CAP_SYS_RAWIO))
return -EPERM;
*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
return 0;
diff -urN /tmp/l97/arch/arm/kernel/ptrace.c lp97/arch/arm/kernel/ptrace.c
--- /tmp/l97/arch/arm/kernel/ptrace.c Sun Apr 12 20:42:15 1998
+++ lp97/arch/arm/kernel/ptrace.c Thu Apr 23 01:38:18 1998
@@ -581,7 +581,7 @@
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
- (current->gid != child->gid)) && !suser())
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
diff -urN /tmp/l97/arch/i386/kernel/ioport.c lp97/arch/i386/kernel/ioport.c
--- /tmp/l97/arch/i386/kernel/ioport.c Thu Apr 2 00:51:41 1998
+++ lp97/arch/i386/kernel/ioport.c Thu Apr 23 03:16:10 1998
@@ -58,7 +58,7 @@

if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
return -EINVAL;
- if (!suser())
+ if (!capable(CAP_SYS_RAWIO))
return -EPERM;
/*
* If it's the first ioperm() call in this thread's lifetime, set the
@@ -94,7 +94,7 @@

if (level > 3)
return -EINVAL;
- if (!suser())
+ if (!capable(CAP_SYS_RAWIO))
return -EPERM;
regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
return 0;
diff -urN /tmp/l97/arch/i386/kernel/ptrace.c lp97/arch/i386/kernel/ptrace.c
--- /tmp/l97/arch/i386/kernel/ptrace.c Thu Mar 12 01:07:20 1998
+++ lp97/arch/i386/kernel/ptrace.c Thu Apr 23 01:24:03 1998
@@ -386,7 +386,7 @@
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
- (current->gid != child->gid)) && !suser())
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
diff -urN /tmp/l97/arch/i386/kernel/vm86.c lp97/arch/i386/kernel/vm86.c
--- /tmp/l97/arch/i386/kernel/vm86.c Sun Mar 29 21:31:16 1998
+++ lp97/arch/i386/kernel/vm86.c Thu Apr 23 01:03:45 1998
@@ -660,7 +660,7 @@
int sig = irqnumber >> 8;
int irq = irqnumber & 255;
handle_irq_zombies();
- if (!suser()) return -EPERM;
+ if (!capable(CAP_SYS_ADMIN)) return -EPERM;
if (!((1 << sig) & ALLOWED_SIGS)) return -EPERM;
if ( (irq<3) || (irq>15) ) return -EPERM;
if (vm86_irqs[irq].tsk) return -EPERM;
diff -urN /tmp/l97/arch/m68k/kernel/ptrace.c lp97/arch/m68k/kernel/ptrace.c
--- /tmp/l97/arch/m68k/kernel/ptrace.c Sat Mar 21 20:04:04 1998
+++ lp97/arch/m68k/kernel/ptrace.c Thu Apr 23 01:31:41 1998
@@ -340,7 +340,7 @@
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
- (current->gid != child->gid)) && !suser())
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
diff -urN /tmp/l97/arch/m68k/kernel/sys_m68k.c lp97/arch/m68k/kernel/sys_m68k.c
--- /tmp/l97/arch/m68k/kernel/sys_m68k.c Fri Feb 13 01:30:12 1998
+++ lp97/arch/m68k/kernel/sys_m68k.c Thu Apr 23 01:32:26 1998
@@ -548,7 +548,7 @@
if (scope == FLUSH_SCOPE_ALL) {
/* Only the superuser may flush the whole cache. */
ret = -EPERM;
- if (!suser ())
+ if (!capable(CAP_SYS_ADMIN))
goto out;
} else {
/* Verify that the specified address region actually belongs to
diff -urN /tmp/l97/arch/mips/kernel/ptrace.c lp97/arch/mips/kernel/ptrace.c
--- /tmp/l97/arch/mips/kernel/ptrace.c Wed Dec 10 19:31:09 1997
+++ lp97/arch/mips/kernel/ptrace.c Thu Apr 23 01:27:57 1998
@@ -289,7 +289,8 @@
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
- (current->gid != child->gid)) && !suser()) {
+ (current->gid != child->gid)) &&
+ !capable(CAP_SYS_PTRACE)) {
res = -EPERM;
goto out;
}
diff -urN /tmp/l97/arch/mips/kernel/sysirix.c lp97/arch/mips/kernel/sysirix.c
--- /tmp/l97/arch/mips/kernel/sysirix.c Wed Dec 10 19:31:10 1997
+++ lp97/arch/mips/kernel/sysirix.c Thu Apr 23 01:30:27 1998
@@ -113,7 +113,7 @@
current->comm, current->pid, (unsigned long) value);
if(value > RLIM_INFINITY)
value = RLIM_INFINITY;
- if(suser()) {
+ if(capable(CAP_SYS_ADMIN)) {
current->rlim[RLIMIT_STACK].rlim_max =
current->rlim[RLIMIT_STACK].rlim_cur = value;
error = value;
@@ -545,7 +545,7 @@
int ret;

lock_kernel();
- if(!suser()) {
+ if(!capable(CAP_SYS_TIME)) {
ret = -EPERM;
goto out;
}
diff -urN /tmp/l97/arch/mips/kernel/sysmips.c lp97/arch/mips/kernel/sysmips.c
--- /tmp/l97/arch/mips/kernel/sysmips.c Wed Dec 10 19:31:10 1997
+++ lp97/arch/mips/kernel/sysmips.c Thu Apr 23 01:29:03 1998
@@ -58,7 +58,7 @@
{
case SETNAME:
retval = -EPERM;
- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
goto out;

name = (char *) arg1;
diff -urN /tmp/l97/arch/ppc/kernel/ptrace.c lp97/arch/ppc/kernel/ptrace.c
--- /tmp/l97/arch/ppc/kernel/ptrace.c Thu Apr 23 00:59:18 1998
+++ lp97/arch/ppc/kernel/ptrace.c Thu Apr 23 01:31:17 1998
@@ -331,7 +331,7 @@
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
- (current->gid != child->gid)) && !suser())
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
diff -urN /tmp/l97/arch/sparc/kernel/ptrace.c lp97/arch/sparc/kernel/ptrace.c
--- /tmp/l97/arch/sparc/kernel/ptrace.c Thu Mar 12 00:44:14 1998
+++ lp97/arch/sparc/kernel/ptrace.c Thu Apr 23 01:27:20 1998
@@ -539,7 +539,8 @@
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
- (current->gid != child->gid)) && !suser()) {
+ (current->gid != child->gid)) &&
+ !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
goto out;
}
diff -urN /tmp/l97/arch/sparc64/kernel/psycho.c lp97/arch/sparc64/kernel/psycho.c
--- /tmp/l97/arch/sparc64/kernel/psycho.c Thu Apr 23 00:59:20 1998
+++ lp97/arch/sparc64/kernel/psycho.c Thu Apr 23 01:36:22 1998
@@ -2323,7 +2323,7 @@
unsigned int uint;
int err = 0;

- if(!suser())
+ if(!capable(CAP_SYS_ADMIN))
return -EPERM;

lock_kernel();
@@ -2361,7 +2361,7 @@
unsigned int uint;
int err = 0;

- if(!suser())
+ if(!capable(CAP_SYS_ADMIN))
return -EPERM;

lock_kernel();
diff -urN /tmp/l97/arch/sparc64/kernel/ptrace.c lp97/arch/sparc64/kernel/ptrace.c
--- /tmp/l97/arch/sparc64/kernel/ptrace.c Tue Jan 13 00:15:44 1998
+++ lp97/arch/sparc64/kernel/ptrace.c Thu Apr 23 01:36:00 1998
@@ -557,7 +557,8 @@
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
- (current->gid != child->gid)) && !suser()) {
+ (current->gid != child->gid)) &&
+ !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
goto out;
}
diff -urN /tmp/l97/arch/sparc64/kernel/sys_sparc32.c lp97/arch/sparc64/kernel/sys_sparc32.c
--- /tmp/l97/arch/sparc64/kernel/sys_sparc32.c Thu Apr 23 00:59:21 1998
+++ lp97/arch/sparc64/kernel/sys_sparc32.c Thu Apr 23 01:33:19 1998
@@ -1366,7 +1366,7 @@
unsigned long type_page;
int err, is_smb, is_ncp;

- if(!suser())
+ if(!capable(CAP_SYS_ADMIN))
return -EPERM;
is_smb = is_ncp = 0;
err = copy_mount_stuff_to_kernel((const void *)A(type), &type_page);
diff -urN /tmp/l97/arch/sparc64/kernel/traps.c lp97/arch/sparc64/kernel/traps.c
--- /tmp/l97/arch/sparc64/kernel/traps.c Thu Apr 23 00:59:21 1998
+++ lp97/arch/sparc64/kernel/traps.c Thu Apr 23 01:35:20 1998
@@ -583,7 +583,7 @@

regs->tpc = regs->tnpc;
regs->tnpc = regs->tnpc + 4;
- if (!suser()) return;
+ if (!capable(CAP_SYS_ADMIN)) return;
size >>= PAGE_SHIFT;
addr = PAGE_OFFSET - PAGE_SIZE;
page = mem_map - 1;
diff -urN /tmp/l97/arch/sparc64/solaris/fs.c lp97/arch/sparc64/solaris/fs.c
--- /tmp/l97/arch/sparc64/solaris/fs.c Thu Apr 23 00:59:21 1998
+++ lp97/arch/sparc64/solaris/fs.c Thu Apr 23 01:37:32 1998
@@ -464,7 +464,7 @@
val <<= 9;
lock_kernel();
if (val > current->rlim[RLIMIT_FSIZE].rlim_max) {
- if (!suser()) {
+ if (!capable(CAP_SYS_RESOURCE)) {
unlock_kernel();
return -EPERM;
}
diff -urN /tmp/l97/include/linux/blk.h lp97/include/linux/blk.h
--- /tmp/l97/include/linux/blk.h Tue Apr 14 22:00:26 1998
+++ lp97/include/linux/blk.h Thu Apr 23 17:37:58 1998
@@ -95,7 +95,7 @@
#endif

#define RO_IOCTLS(dev,where) \
- case BLKROSET: { int __val; if (!suser()) return -EACCES; \
+ case BLKROSET: { int __val; if (!capable(CAP_SYS_ADMIN)) return -EACCES; \
if (get_user(__val, (int *)(where))) return -EFAULT; \
set_device_ro((dev),__val); return 0; } \
case BLKROGET: { int __val = (is_read_only(dev) != 0) ; \
diff -urN /tmp/l97/include/linux/capability.h lp97/include/linux/capability.h
--- /tmp/l97/include/linux/capability.h Tue Apr 14 22:00:11 1998
+++ lp97/include/linux/capability.h Thu Apr 23 17:30:24 1998
@@ -19,16 +19,14 @@

#define _LINUX_CAPABILITY_VERSION 0x19980330

-typedef struct _user_cap_struct {
- __u32 version;
- __u32 size;
- __u8 cap[1];
+typedef struct __user_cap_struct {
+ __u32 cap[1];
} *cap_t;

#ifdef __KERNEL__

typedef struct kernel_cap_struct {
- int cap;
+ __u32 cap;
} kernel_cap_t;

#endif
@@ -46,13 +44,13 @@

/* Override all DAC access, including ACL execute access if
[_POSIX_ACL] is defined. Excluding DAC access covered by
- CAP_LINUX_IMMUTABLE */
+ CAP_LINUX_IMMUTABLE. */

#define CAP_DAC_OVERRIDE 1

/* Overrides all DAC restrictions regarding read and search on files
and directories, including ACL restrictions if [_POSIX_ACL] is
- defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE */
+ defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */

#define CAP_DAC_READ_SEARCH 2

@@ -82,10 +80,13 @@
#define CAP_KILL 5

/* Allows setgid(2) manipulation */
+/* Allows setgroups(2) */
+/* Allows forged gids on socket credentials passing. */

#define CAP_SETGID 6

-/* Allows setuid(2) manipulation */
+/* Allows set*uid(2) manipulation (including fsuid). */
+/* Allows forged pids on socket credentials passing. */

#define CAP_SETUID 7

@@ -112,9 +113,17 @@
#define CAP_NET_BROADCAST 11

/* Allow interface configuration */
-/* Allow configuring of firewall stuff */
+/* Allow administration of IP firewall, masquerading and accounting */
/* Allow setting debug option on sockets */
/* Allow modification of routing tables */
+/* Allow setting arbitrary process / process group ownership on
+ sockets */
+/* Allow binding to any address for transparent proxying */
+/* Allow setting TOS (type of service) */
+/* Allow setting promiscuous mode */
+/* Allow clearing driver statistics */
+/* Allow multicasting */
+/* Allow read/write of device-specific registers */

#define CAP_NET_ADMIN 12

@@ -123,7 +132,9 @@

#define CAP_NET_RAW 13

-/* Allow locking of segments in memory */
+/* Allow locking of shared memory segments */
+/* Allow mlock and mlockall (which doesn't really have anything to do
+ with IPC) */

#define CAP_IPC_LOCK 14

@@ -153,9 +164,42 @@

/* Allow configuration of the secure attention key */
/* Allow administration of the random device */
-/* Allow device administration */
+/* Allow device administration (mknod)*/
/* Allow examination and configuration of disk quotas */
-/* System Admin functions: mount et al */
+/* Allow configuring the kernel's syslog (printk behaviour) */
+/* Allow sending a signal to any process */
+/* Allow setting the domainname */
+/* Allow setting the hostname */
+/* Allow calling bdflush() */
+/* Allow mount() and umount(), setting up new smb connection */
+/* Allow some autofs root ioctls */
+/* Allow nfsservctl */
+/* Allow VM86_REQUEST_IRQ */
+/* Allow to read/write pci config on alpha */
+/* Allow irix_prctl on mips (setstacksize) */
+/* Allow flushing all cache on m68k (sys_cacheflush) */
+/* Allow removing semaphores */
+/* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
+ and shared memory */
+/* Allow locking/unlocking of shared memory segment */
+/* Allow turning swap on/off */
+/* Allow forged pids on socket credentials passing */
+/* Allow setting readahead and flushing buffers on block devices */
+/* Allow setting geometry in floppy driver */
+/* Allow turning DMA on/off in xd driver */
+/* Allow administration of md devices (mostly the above, but some
+ extra ioctls) */
+/* Allow tuning the ide driver */
+/* Allow access to the nvram device */
+/* Allow administration of apm_bios, serial and bttv (TV) device */
+/* Allow manufacturer commands in isdn CAPI support driver */
+/* Allow reading non-standardized portions of pci configuration space */
+/* Allow DDI debug ioctl on sbpcd driver */
+/* Allow setting up serial ports */
+/* Allow sending raw qic-117 commands */
+/* Allow enabling/disabling tagged queuing on SCSI controllers and sending
+ arbitrary SCSI commands */
+/* Allow setting encryption key on loopback filesystem */

#define CAP_SYS_ADMIN 21

@@ -163,19 +207,34 @@

#define CAP_SYS_BOOT 22

-/* Allow use of renice() on others, and raising of priority */
+/* Allow raising priority and setting priority on other (different
+ UID) processes */
+/* Allow use of FIFO and round-robin (realtime) scheduling on own
+ processes and setting the scheduling algorithm used by another
+ process. */

#define CAP_SYS_NICE 23

-/* Override resource limits */
+/* Override resource limits. Set resource limits. */
+/* Override quota limits. */
+/* Override reserved space on ext2 filesystem */
+/* NOTE: ext2 honors fsuid when checking for resource overrides, so
+ you can override using fsuid too */
+/* Override size restrictions on IPC message queues */
+/* Allow more than 64hz interrupts from the real-time clock */
+/* Override max number of consoles on console allocation */
+/* Override max number of keymaps */

#define CAP_SYS_RESOURCE 24

/* Allow manipulation of system clock */
+/* Allow irix_stime on mips */
+/* Allow setting the real-time clock */

#define CAP_SYS_TIME 25

/* Allow configuration of tty devices */
+/* Allow vhangup() of tty */

#define CAP_SYS_TTY_CONFIG 26

@@ -187,6 +246,8 @@

#define CAP_EMPTY_SET { 0 }
#define CAP_FULL_SET { ~0 }
+#define CAP_INIT_EFF_SET { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }
+#define CAP_INIT_INH_SET { ~0 & ~CAP_TO_MASK(CAP_SETPCAP) }

#define CAP_TO_MASK(x) (1 << (x))
#define cap_raise(c, flag) (c.cap |= CAP_TO_MASK(flag))
@@ -196,8 +257,9 @@
#define cap_isclear(c) (!c.cap)

#define cap_copy(dest,src) do { (dest).cap = (src).cap; } while(0)
-#define cap_clear(c) do { c.cap = 0; } while(0)
-#define cap_set_full(c) do { c.cap = ~0; } while(0)
+#define cap_clear(c) do { (c).cap = 0; } while(0)
+#define cap_set_full(c) do { (c).cap = ~0; } while(0)
+#define cap_mask(c,mask) do { (c).cap &= (mask).cap; } while(0)

#define cap_is_fs_cap(c) ((c) & CAP_FS_MASK)

diff -urN /tmp/l97/include/linux/sched.h lp97/include/linux/sched.h
--- /tmp/l97/include/linux/sched.h Tue Apr 14 22:00:12 1998
+++ lp97/include/linux/sched.h Thu Apr 23 17:37:34 1998
@@ -354,7 +354,7 @@
/* process credentials */ \
/* uid etc */ 0,0,0,0,0,0,0,0, \
/* suppl grps*/ 0, {0,}, \
-/* caps */ CAP_FULL_SET, CAP_FULL_SET, CAP_FULL_SET, \
+/* caps */ CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \
/* rlimits */ INIT_RLIMITS, \
/* math */ 0, \
/* comm */ "swapper", \
diff -urN /tmp/l97/ipc/msg.c lp97/ipc/msg.c
--- /tmp/l97/ipc/msg.c Sun Mar 15 19:25:43 1998
+++ lp97/ipc/msg.c Thu Apr 23 01:51:32 1998
@@ -477,9 +477,10 @@
case IPC_SET:
err = -EPERM;
if (current->euid != ipcp->cuid &&
- current->euid != ipcp->uid && !suser())
+ current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
+ /* We _could_ check for CAP_CHOWN above, but we don't */
goto out;
- if (tbuf.msg_qbytes > MSGMNB && !suser())
+ if (tbuf.msg_qbytes > MSGMNB && !capable(CAP_SYS_RESOURCE))
goto out;
msq->msg_qbytes = tbuf.msg_qbytes;
ipcp->uid = tbuf.msg_perm.uid;
@@ -492,7 +493,7 @@
case IPC_RMID:
err = -EPERM;
if (current->euid != ipcp->cuid &&
- current->euid != ipcp->uid && !suser())
+ current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
goto out;

freeque (id);
diff -urN /tmp/l97/ipc/sem.c lp97/ipc/sem.c
--- /tmp/l97/ipc/sem.c Mon Dec 22 02:11:08 1997
+++ lp97/ipc/sem.c Thu Apr 23 01:51:13 1998
@@ -482,7 +482,8 @@
goto out;
break;
case IPC_RMID:
- if (current->euid == ipcp->cuid || current->euid == ipcp->uid || suser()) {
+ if (current->euid == ipcp->cuid ||
+ current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) {
freeary (id);
err = 0;
goto out;
@@ -540,7 +541,8 @@
update_queue(sma);
break;
case IPC_SET:
- if (current->euid == ipcp->cuid || current->euid == ipcp->uid || suser()) {
+ if (current->euid == ipcp->cuid ||
+ current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) {
ipcp->uid = tbuf.sem_perm.uid;
ipcp->gid = tbuf.sem_perm.gid;
ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
diff -urN /tmp/l97/ipc/shm.c lp97/ipc/shm.c
--- /tmp/l97/ipc/shm.c Mon Mar 30 10:21:41 1998
+++ lp97/ipc/shm.c Thu Apr 23 02:10:49 1998
@@ -306,7 +306,7 @@
switch (cmd) {
case SHM_UNLOCK:
err = -EPERM;
- if (!suser())
+ if (!capable(CAP_IPC_LOCK))
goto out;
err = -EINVAL;
if (!(ipcp->mode & SHM_LOCKED))
@@ -318,7 +318,7 @@
/* Should the pages be faulted in here or leave it to user? */
/* need to determine interaction with current->swappable */
err = -EPERM;
- if (!suser())
+ if (!capable(CAP_IPC_LOCK))
goto out;
err = -EINVAL;
if (ipcp->mode & SHM_LOCKED)
@@ -347,7 +347,8 @@
break;
case IPC_SET:
if (current->euid == shp->shm_perm.uid ||
- current->euid == shp->shm_perm.cuid || suser()) {
+ current->euid == shp->shm_perm.cuid ||
+ capable(CAP_SYS_ADMIN)) {
ipcp->uid = tbuf.shm_perm.uid;
ipcp->gid = tbuf.shm_perm.gid;
ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
@@ -359,7 +360,8 @@
goto out;
case IPC_RMID:
if (current->euid == shp->shm_perm.uid ||
- current->euid == shp->shm_perm.cuid || suser()) {
+ current->euid == shp->shm_perm.cuid ||
+ capable(CAP_SYS_ADMIN)) {
shp->shm_perm.mode |= SHM_DEST;
if (shp->shm_nattch <= 0)
killseg (id);
diff -urN /tmp/l97/ipc/util.c lp97/ipc/util.c
--- /tmp/l97/ipc/util.c Tue Mar 10 23:43:13 1998
+++ lp97/ipc/util.c Thu Apr 23 02:12:12 1998
@@ -47,8 +47,10 @@
else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
granted_mode >>= 3;
/* is there some bit set in requested_mode but not in granted_mode? */
- if ((requested_mode & ~granted_mode & 0007) && !suser())
+ if ((requested_mode & ~granted_mode & 0007) &&
+ !capable(CAP_IPC_OWNER))
return -1;
+
return 0;
}

diff -urN /tmp/l97/kernel/acct.c lp97/kernel/acct.c
--- /tmp/l97/kernel/acct.c Sat Feb 28 22:33:49 1998
+++ lp97/kernel/acct.c Mon Apr 20 23:56:14 1998
@@ -119,7 +119,7 @@
int error = -EPERM;

lock_kernel();
- if (!suser())
+ if (!capable(CAP_SYS_PACCT))
goto out;

if (name == (char *)NULL) {
diff -urN /tmp/l97/kernel/module.c lp97/kernel/module.c
--- /tmp/l97/kernel/module.c Tue Mar 10 23:43:13 1998
+++ lp97/kernel/module.c Mon Apr 20 23:56:14 1998
@@ -120,7 +120,7 @@
struct module *mod;

lock_kernel();
- if (!suser()) {
+ if (!capable(CAP_SYS_MODULE)) {
error = -EPERM;
goto err0;
}
@@ -175,7 +175,7 @@
struct module_ref *dep;

lock_kernel();
- if (!suser())
+ if (!capable(CAP_SYS_MODULE))
goto err0;
if ((namelen = get_mod_name(name_user, &name)) < 0) {
error = namelen;
@@ -366,7 +366,7 @@
int something_changed;

lock_kernel();
- if (!suser())
+ if (!capable(CAP_SYS_MODULE))
goto out;

if (name_user) {
diff -urN /tmp/l97/kernel/printk.c lp97/kernel/printk.c
--- /tmp/l97/kernel/printk.c Mon Apr 13 23:41:53 1998
+++ lp97/kernel/printk.c Mon Apr 20 23:56:14 1998
@@ -130,7 +130,7 @@
int error = -EPERM;

lock_kernel();
- if ((type != 3) && !suser())
+ if ((type != 3) && !capable(CAP_SYS_ADMIN))
goto out;
error = 0;
switch (type) {
diff -urN /tmp/l97/kernel/sched.c lp97/kernel/sched.c
--- /tmp/l97/kernel/sched.c Thu Apr 2 02:26:35 1998
+++ lp97/kernel/sched.c Mon Apr 20 23:56:14 1998
@@ -1227,7 +1227,7 @@

newprio = increment;
if (increment < 0) {
- if (!suser())
+ if (!capable(CAP_SYS_NICE))
return -EPERM;
newprio = -increment;
increase = 1;
@@ -1322,10 +1322,11 @@
goto out_unlock;

retval = -EPERM;
- if ((policy == SCHED_FIFO || policy == SCHED_RR) && !suser())
+ if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
+ !capable(CAP_SYS_NICE))
goto out_unlock;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
- !suser())
+ !capable(CAP_SYS_NICE))
goto out_unlock;

retval = 0;
diff -urN /tmp/l97/kernel/signal.c lp97/kernel/signal.c
--- /tmp/l97/kernel/signal.c Tue Apr 14 01:47:48 1998
+++ lp97/kernel/signal.c Mon Apr 20 23:56:14 1998
@@ -235,7 +235,7 @@
&& ((sig != SIGCONT) || (current->session != t->session))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
- && !suser())
+ && !capable(CAP_SYS_ADMIN))
goto out_nolock;

/* The null signal is a permissions and process existance probe.
diff -urN /tmp/l97/kernel/sys.c lp97/kernel/sys.c
--- /tmp/l97/kernel/sys.c Thu Apr 23 00:59:29 1998
+++ lp97/kernel/sys.c Wed Apr 22 00:10:34 1998
@@ -114,13 +114,13 @@
if (!proc_sel(p, which, who))
continue;
if (p->uid != current->euid &&
- p->uid != current->uid && !suser()) {
+ p->uid != current->uid && !capable(CAP_SYS_NICE)) {
error = EPERM;
continue;
}
if (error == ESRCH)
error = 0;
- if (priority > p->priority && !suser())
+ if (priority > p->priority && !capable(CAP_SYS_NICE))
error = EACCES;
else
p->priority = priority;
@@ -172,7 +172,7 @@
char buffer[256];

/* We only trust the superuser with rebooting the system. */
- if (!suser())
+ if (!capable(CAP_SYS_BOOT))
return -EPERM;

/* For safety, we require "magic" arguments. */
@@ -273,7 +273,7 @@
if (rgid != (gid_t) -1) {
if ((old_rgid == rgid) ||
(current->egid==rgid) ||
- suser())
+ capable(CAP_SETGID))
current->gid = rgid;
else
return -EPERM;
@@ -282,7 +282,7 @@
if ((old_rgid == egid) ||
(current->egid == egid) ||
(current->sgid == egid) ||
- suser())
+ capable(CAP_SETGID))
current->fsgid = current->egid = egid;
else {
current->gid = old_rgid;
@@ -307,7 +307,7 @@
{
int old_egid = current->egid;

- if (suser())
+ if (capable(CAP_SETGID))
current->gid = current->egid = current->sgid = current->fsgid = gid;
else if ((gid == current->gid) || (gid == current->sgid))
current->egid = current->fsgid = gid;
@@ -319,6 +319,41 @@
return 0;
}

+/*
+ * cap_emulate_setxuid() fixes the effective / permitted capabilities of
+ * a process after a call to setuid, setreuid, or setresuid.
+ *
+ * 1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
+ * {r,e,s}uid != 0, the permitted and effective capabilities are
+ * cleared.
+ *
+ * 2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
+ * capabilities of the process are cleared.
+ *
+ * 3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
+ * capabilities are set to the permitted capabilities.
+ *
+ * fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should
+ * never happen.
+ *
+ * -astor
+ */
+extern inline void cap_emulate_setxuid(int old_ruid, int old_euid,
+ int old_suid)
+{
+ if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
+ (current->uid != 0 && current->euid != 0 && current->suid != 0)) {
+ cap_clear(current->cap_permitted);
+ cap_clear(current->cap_effective);
+ }
+ if (old_euid == 0 && current->euid != 0) {
+ cap_clear(current->cap_effective);
+ }
+ if (old_euid != 0 && current->euid == 0) {
+ cap_copy(current->cap_effective, current->cap_permitted);
+ }
+}
+
/*
* Unprivileged users may change the real uid to the effective uid
* or vice versa. (BSD-style)
@@ -336,14 +371,15 @@
*/
asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
{
- int old_ruid, old_euid, new_ruid;
+ int old_ruid, old_euid, old_suid, new_ruid;

new_ruid = old_ruid = current->uid;
old_euid = current->euid;
+ old_suid = current->suid;
if (ruid != (uid_t) -1) {
if ((old_ruid == ruid) ||
(current->euid==ruid) ||
- suser())
+ capable(CAP_SETUID))
new_ruid = ruid;
else
return -EPERM;
@@ -352,7 +388,7 @@
if ((old_ruid == euid) ||
(current->euid == euid) ||
(current->suid == euid) ||
- suser())
+ capable(CAP_SETUID))
current->fsuid = current->euid = euid;
else
return -EPERM;
@@ -375,9 +411,16 @@
if(new_ruid)
charge_uid(current, 1);
}
+
+ if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+ cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+ }
+
return 0;
}

+
+
/*
* setuid() is implemented like SysV w/ SAVED_IDS
*
@@ -392,10 +435,11 @@
asmlinkage int sys_setuid(uid_t uid)
{
int old_euid = current->euid;
- int old_ruid, new_ruid;
+ int old_ruid, old_suid, new_ruid;

old_ruid = new_ruid = current->uid;
- if (suser())
+ old_suid = current->suid;
+ if (capable(CAP_SETUID))
new_ruid = current->euid = current->suid = current->fsuid = uid;
else if ((uid == current->uid) || (uid == current->suid))
current->fsuid = current->euid = uid;
@@ -412,6 +456,11 @@
if(new_ruid)
charge_uid(current, 1);
}
+
+ if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+ cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+ }
+
return 0;
}

@@ -422,6 +471,9 @@
*/
asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
+ int old_ruid = current->uid;
+ int old_euid = current->euid;
+ int old_suid = current->suid;
if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
(ruid != current->euid) && (ruid != current->suid))
@@ -448,6 +500,11 @@
}
if (suid != (uid_t) -1)
current->suid = suid;
+
+ if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+ cap_emulate_setxuid(old_ruid, old_euid, old_suid);
+ }
+
return 0;
}

@@ -515,11 +572,31 @@

old_fsuid = current->fsuid;
if (uid == current->uid || uid == current->euid ||
- uid == current->suid || uid == current->fsuid || suser())
+ uid == current->suid || uid == current->fsuid ||
+ capable(CAP_SETUID))
current->fsuid = uid;
if (current->fsuid != old_fsuid)
current->dumpable = 0;

+ /* We emulate fsuid by essentially doing a scaled-down version
+ * of what we did in setresuid and friends. However, we only
+ * operate on the fs-specific bits of the process' effective
+ * capabilities
+ *
+ * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
+ * if not, we might be a bit too harsh here.
+ */
+
+ if (!issecure(SECURE_NO_SETUID_FIXUP)) {
+ if (old_fsuid == 0 && current->fsuid != 0) {
+ current->cap_effective.cap &= ~CAP_FS_MASK;
+ }
+ if (old_fsuid != 0 && current->fsuid == 0) {
+ current->cap_effective.cap |=
+ (current->cap_permitted.cap & CAP_FS_MASK);
+ }
+ }
+
return old_fsuid;
}

@@ -532,7 +609,8 @@

old_fsgid = current->fsgid;
if (gid == current->gid || gid == current->egid ||
- gid == current->sgid || gid == current->fsgid || suser())
+ gid == current->sgid || gid == current->fsgid ||
+ capable(CAP_SETGID))
current->fsgid = gid;
if (current->fsgid != old_fsgid)
current->dumpable = 0;
@@ -716,7 +794,7 @@

asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
{
- if (!suser())
+ if (!capable(CAP_SETGID))
return -EPERM;
if ((unsigned) gidsetsize > NGROUPS)
return -EINVAL;
@@ -756,7 +834,7 @@

asmlinkage int sys_sethostname(char *name, int len)
{
- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
@@ -787,7 +865,7 @@
*/
asmlinkage int sys_setdomainname(char *name, int len)
{
- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
@@ -820,7 +898,7 @@
old_rlim = current->rlim + resource;
if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
(new_rlim.rlim_max > old_rlim->rlim_max)) &&
- !suser())
+ !capable(CAP_SYS_RESOURCE))
return -EPERM;
if (resource == RLIMIT_NOFILE) {
if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
diff -urN /tmp/l97/kernel/time.c lp97/kernel/time.c
--- /tmp/l97/kernel/time.c Fri Feb 13 01:44:15 1998
+++ lp97/kernel/time.c Mon Apr 20 23:56:14 1998
@@ -87,7 +87,7 @@
{
int value;

- if (!suser())
+ if (!capable(CAP_SYS_TIME))
return -EPERM;
if (get_user(value, tptr))
return -EFAULT;
@@ -156,7 +156,7 @@
{
static int firsttime = 1;

- if (!suser())
+ if (!capable(CAP_SYS_TIME))
return -EPERM;

if (tz) {
@@ -221,7 +221,7 @@
long ltemp, mtemp, save_adjust;

/* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !suser())
+ if (txc->modes && !capable(CAP_SYS_TIME))
return -EPERM;

/* Now we validate the data before disabling interrupts */
diff -urN /tmp/l97/mm/mlock.c lp97/mm/mlock.c
--- /tmp/l97/mm/mlock.c Fri Feb 27 19:53:07 1998
+++ lp97/mm/mlock.c Thu Apr 23 02:02:27 1998
@@ -144,7 +144,7 @@
struct vm_area_struct * vma, * next;
int error;

- if (!suser())
+ if (!capable(CAP_IPC_LOCK))
return -EPERM;
len = (len + ~PAGE_MASK) & PAGE_MASK;
end = start + len;
@@ -235,7 +235,7 @@
unsigned int def_flags;
struct vm_area_struct * vma;

- if (!suser())
+ if (!capable(CAP_IPC_LOCK))
return -EPERM;

def_flags = 0;
diff -urN /tmp/l97/mm/swapfile.c lp97/mm/swapfile.c
--- /tmp/l97/mm/swapfile.c Tue Apr 7 02:48:34 1998
+++ lp97/mm/swapfile.c Thu Apr 23 02:02:52 1998
@@ -356,7 +356,7 @@
int err = -EPERM;

lock_kernel();
- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
goto out;

dentry = namei(specialfile);
@@ -491,7 +491,7 @@
static int least_priority = 0;

lock_kernel();
- if (!suser())
+ if (!capable(CAP_SYS_ADMIN))
goto out;
memset(&filp, 0, sizeof(filp));
p = swap_info;
\
 
 \ /
  Last update: 2005-03-22 13:42    [W:0.048 / U:2.492 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site