Linux – How an unprivileged user could kill a process she didn’t start

databasekilllinuxprocesssignal

I stumbled upon something very surprising which I cannot understand on a Red Hat EL 5.6 box : the user hri (which is in the group dba) is able to kill processes owned by user oracle (which is also in group dba).

Is anybody able to explain what could allow an unprivileged user to kill another user's processes? Even if Oracle process was written to handle signals, I though processes could not trap SIGKILL(9).

Below is a session log which shows that.

OracleServer:/home/hri> export ORACLE_SID=HRIXXXDW

OracleServer:/home/hri> sqlplus / as sysdba

SQL*Plus: Release 10.2.0.5.0 - Production on Thu Dec 12 17:30:56 2013

Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

Connected to an idle instance.

SQL> startup
ORA-09925: Unable to create audit trail file
Linux-x86_64 Error: 13: Permission denied
Additional information: 9925
SQL> Disconnected

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      28295  0.0  0.0  61164   676 pts/9    S+   17:31   0:00                  \_ grep HRIXXX
oracle   28263  0.0  0.0 759668 17384 ?        Ss   17:31   0:00 ora_pmon_HRIXXXDW
oracle   28265  0.0  0.0 758488 16576 ?        Ss   17:31   0:00 ora_psp0_HRIXXXDW
oracle   28267  0.1  0.0 758488 23948 ?        Ss   17:31   0:00 ora_mman_HRIXXXDW
oracle   28269  0.0  0.0 760968 19308 ?        Ss   17:31   0:00 ora_dbw0_HRIXXXDW
oracle   28271  0.0  0.0 760960 19284 ?        Ss   17:31   0:00 ora_dbw1_HRIXXXDW
oracle   28273  0.0  0.0 758488 16656 ?        Ss   17:31   0:00 ora_lgwr_HRIXXXDW
oracle   28275  0.0  0.0 758492 19092 ?        Ss   17:31   0:00 ora_ckpt_HRIXXXDW
oracle   28277  0.0  0.0 758488 16596 ?        Ss   17:31   0:00 ora_smon_HRIXXXDW
oracle   28279  0.0  0.0 758488 16588 ?        Ss   17:31   0:00 ora_reco_HRIXXXDW
oracle   28281  0.0  0.0 758488 16772 ?        Ss   17:31   0:00 ora_mmon_HRIXXXDW
oracle   28283  0.0  0.0 758488 16612 ?        Ss   17:31   0:00 ora_mmnl_HRIXXXDW

OracleServer:/home/hri> /bin/kill -9 28263

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      28309  0.0  0.0  61164   676 pts/9    S+   17:31   0:00                  \_ grep HRIXXX
oracle   28265  0.0  0.0 758488 16584 ?        Ss   17:31   0:00 ora_psp0_HRIXXXDW
oracle   28267  0.0  0.0 758488 23948 ?        Ss   17:31   0:00 ora_mman_HRIXXXDW
oracle   28269  0.0  0.0 760968 19316 ?        Ss   17:31   0:00 ora_dbw0_HRIXXXDW
oracle   28271  0.0  0.0 760960 19284 ?        Ss   17:31   0:00 ora_dbw1_HRIXXXDW
oracle   28273  0.0  0.0 758488 16656 ?        Ss   17:31   0:00 ora_lgwr_HRIXXXDW
oracle   28275  0.0  0.0 758492 19096 ?        Ss   17:31   0:00 ora_ckpt_HRIXXXDW
oracle   28277  0.0  0.0 758488 16596 ?        Ss   17:31   0:00 ora_smon_HRIXXXDW
oracle   28279  0.0  0.0 758488 16588 ?        Ss   17:31   0:00 ora_reco_HRIXXXDW
oracle   28281  0.0  0.0 758488 16772 ?        Ss   17:31   0:00 ora_mmon_HRIXXXDW
oracle   28283  0.0  0.0 758488 16620 ?        Ss   17:31   0:00 ora_mmnl_HRIXXXDW

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      28435  0.0  0.0  61164   676 pts/9    S+   17:32   0:00                  \_ grep HRIXXX

Below are a kill -15 then a kill -9, with strace :

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      26278  0.0  0.0  61164   676 pts/9    S+   17:16   0:00                  \_ grep HRIXXX
oracle   12412  0.0  0.0 759660 19724 ?        Ss   16:10   0:00 ora_pmon_HRIXXXDW
oracle   12414  0.0  0.0 758484 16608 ?        Ss   16:10   0:00 ora_psp0_HRIXXXDW
oracle   12416  0.0  0.0 758484 23992 ?        Ss   16:10   0:00 ora_mman_HRIXXXDW
oracle   12418  0.0  0.0 760980 19352 ?        Ss   16:10   0:00 ora_dbw0_HRIXXXDW
oracle   12420  0.0  0.0 760968 19316 ?        Ss   16:10   0:00 ora_dbw1_HRIXXXDW
oracle   12422  0.0  0.0 758484 16700 ?        Ss   16:10   0:00 ora_lgwr_HRIXXXDW
oracle   12424  0.0  0.0 758504 19152 ?        Ss   16:10   0:00 ora_ckpt_HRIXXXDW
oracle   12426  0.0  0.0 758484 16708 ?        Ss   16:10   0:00 ora_smon_HRIXXXDW
oracle   12428  0.0  0.0 758484 16616 ?        Ss   16:10   0:00 ora_reco_HRIXXXDW
oracle   12430  0.0  0.0 758484 16812 ?        Ss   16:10   0:00 ora_mmon_HRIXXXDW
oracle   12432  0.0  0.0 758484 16644 ?        Ss   16:10   0:00 ora_mmnl_HRIXXXDW

OracleServer:/home/hri> strace kill 12414
execve("/bin/kill", ["kill", "12414"], [/* 32 vars */]) = 0
brk(0)                                  = 0xe36e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25c7756000
uname({sys="Linux", node="
OracleServer", ...})  = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=101954, ...}) = 0
mmap(NULL, 101954, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b25c7757000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\332\301\302;\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1722304, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25c7770000
mmap(0x3bc2c00000, 3502424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3bc2c00000
mprotect(0x3bc2d4e000, 2097152, PROT_NONE) = 0
mmap(0x3bc2f4e000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14e000) = 0x3bc2f4e000
mmap(0x3bc2f53000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3bc2f53000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25c7771000
arch_prctl(ARCH_SET_FS, 0x2b25c7771260) = 0
mprotect(0x3bc2f4e000, 16384, PROT_READ) = 0
mprotect(0x3bc2a1b000, 4096, PROT_READ) = 0
munmap(0x2b25c7757000, 101954)          = 0
brk(0)                                  = 0xe36e000
brk(0xe38f000)                          = 0xe38f000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=56450560, ...}) = 0
mmap(NULL, 56450560, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b25c7772000
close(3)                                = 0
kill(12414, SIGTERM)                    = 0
exit_group(0)                           = ?

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      26328  0.0  0.0  61164   676 pts/9    S+   17:16   0:00                  \_ grep HRIXXX
oracle   12412  0.0  0.0 759660 19724 ?        Ss   16:10   0:00 ora_pmon_HRIXXXDW
oracle   12414  0.0  0.0 758484 16608 ?        Ss   16:10   0:00 ora_psp0_HRIXXXDW
oracle   12416  0.0  0.0 758484 23992 ?        Ss   16:10   0:00 ora_mman_HRIXXXDW
oracle   12418  0.0  0.0 760980 19352 ?        Ss   16:10   0:00 ora_dbw0_HRIXXXDW
oracle   12420  0.0  0.0 760968 19316 ?        Ss   16:10   0:00 ora_dbw1_HRIXXXDW
oracle   12422  0.0  0.0 758484 16700 ?        Ss   16:10   0:00 ora_lgwr_HRIXXXDW
oracle   12424  0.0  0.0 758504 19152 ?        Ss   16:10   0:00 ora_ckpt_HRIXXXDW
oracle   12426  0.0  0.0 758484 16708 ?        Ss   16:10   0:00 ora_smon_HRIXXXDW
oracle   12428  0.0  0.0 758484 16616 ?        Ss   16:10   0:00 ora_reco_HRIXXXDW
oracle   12430  0.0  0.0 758484 16812 ?        Ss   16:10   0:00 ora_mmon_HRIXXXDW
oracle   12432  0.0  0.0 758484 16644 ?        Ss   16:10   0:00 ora_mmnl_HRIXXXDW

OracleServer:/home/hri> strace kill -9 12414
execve("/bin/kill", ["kill", "-9", "12414"], [/* 32 vars */]) = 0
brk(0)                                  = 0x1b155000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ac77c2e4000
uname({sys="Linux", node="
OracleServer", ...})  = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=101954, ...}) = 0
mmap(NULL, 101954, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2ac77c2e5000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\332\301\302;\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1722304, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ac77c2fe000
mmap(0x3bc2c00000, 3502424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3bc2c00000
mprotect(0x3bc2d4e000, 2097152, PROT_NONE) = 0
mmap(0x3bc2f4e000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14e000) = 0x3bc2f4e000
mmap(0x3bc2f53000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3bc2f53000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ac77c2ff000
arch_prctl(ARCH_SET_FS, 0x2ac77c2ff260) = 0
mprotect(0x3bc2f4e000, 16384, PROT_READ) = 0
mprotect(0x3bc2a1b000, 4096, PROT_READ) = 0
munmap(0x2ac77c2e5000, 101954)          = 0
brk(0)                                  = 0x1b155000
brk(0x1b176000)                         = 0x1b176000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=56450560, ...}) = 0
mmap(NULL, 56450560, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2ac77c300000
close(3)                                = 0
kill(12414, SIGKILL)                    = 0
exit_group(0)                           = ?

OracleServer:/home/hri> ps auxf | grep HRIXXX
hri      26380  0.0  0.0  61164   676 pts/9    S+   17:17   0:00                  \_ grep HRIXXX

Now some information on the users and the OS:

OracleServer:/home/hri> uname -a
Linux OracleServer 2.6.18-186.el5 #1 SMP Wed Jan 27 18:11:22 EST 2010 x86_64 x86_64 x86_64 GNU/Linux

OracleServer:/home/hri> cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.6 (Tikanga)

OracleServer:/home/hri> id
uid=20314(hri) gid=20175(hri) groups=20001(dba),20175(hri)

OracleServer:/home/hri> id oracle
uid=20001(oracle) gid=20001(dba) groups=20001(dba),20000(xxxxx),20768(xxxxx),20329(xxxxx),20767(xxxxx),20930(xxxxx),20271(xxxxx),20316(xxxxx)

OracleServer:/home/hri> alias kill
bash: alias: kill: not found

OracleServer:/home/hri> type kill
kill is a shell builtin

OracleServer:/home/hri> which kill
/bin/kill

OracleServer:/home/hri> l /bin/kill
-rwxr-xr-x 1 root root 14864 Sep 22  2010 /bin/kill

OracleServer:/home/hri> file /bin/kill
/bin/kill: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped

Edit, thanks to jjlin comment:

It is hri user who started the $ORACLE_SID (this is what is shown on the first session log posted).

Permissions on oracle binary shown a suid and sgid set.

OracleServer:/home/hri> l /oracle/product/10.2.0.5/bin/oracle
-rwsr-s--x 1 oracle dba 116208733 Jul  1 09:29 /oracle/product/10.2.0.5/bin/oracle

And indeed, the /proc/*/status's Uid line shows that Real UID is 20314 (which is the user id of hri) while Effective UID is 20001 (which is oracle).

OracleServer:/home/hri> ps auxf | grep HRIXXX | grep 9609
oracle    9609  0.0  0.0 759668 19692 ?        Ss   08:41   0:00 ora_pmon_HRIXXXDW

OracleServer:/home/hri> grep [UG]id: /proc/9609/status
Uid:    20314   20001   20001   20001
Gid:    20175   20001   20001   20001

So it must be that: Oracle does run its System ID (SID) sub-processes as Real UID of database owner, while the Effective UID is Oracle's.

Thank you!

References:

Best Answer

Oracle runs its SID sub-processes as Real UID of database owner (hri here), while the Effective UID is Oracle's (oracle). Which is why hri was able to kill what was actually its own processes.

You can use ps axf -O ruid,ruser,euid,euser to display side-by-side both RUID and EUID.

Related Question