Writing Secure Privileged Programs
Writing Secure Privileged Programs
Privileged Programs
linux.conf.au 2010
Wellington, New Zealand; 22 Jan 2010
Michael Kerrisk, jambit GmbH
ht t p: / / www. ker nel . or g/ doc/ man- pages/
ht t p: / / www. man7. or g/
2
2
Overview
2
3
3
Introduction
Authentication techniques
Virtualization
Cross-site scripting
SQL injection
etc.
4
4
Topics
Process credentials
Gaining privileges
Why worry?
Useful reading
5
5
Process
Credentials
6
6
6
Process credentials
Credentials determine:
Ownership of process
EUID == 0 vs EUID != 0
(Described later)
(Described later)
Otherwise:
granted permissions for other
User perms can be < group perms; & group < other
10
10
Gaining
Privileges
20
11
11
Gaining privileges
RUID: unchanged
No EUID unchanged
Example:
Login as mtk
$ whoami
mt k
RUID == EUID == SUID == <mtk>
$ ls -l prog
- r wsr - xr - x 1 root r oot 302585 J an 22 10: 05 pr og
$ ./prog # Cr eat e new pr ocess t hat execs " pr og"
RUID == <mtk>; EUID == SUID == <root (0)>
16
16
33
Why Worry?
17
17
What's the problem?
Some guidelines...
18
18
Guidelines
35
19
19
Click to add title
Guideline: Avoid writing setuid-
root programs
20
20
Setuid-root? Just say no!
Privilege separation
Example:
Examples:
e.g.,:
open a file for writing on a read-only file system;
fork() fails if process table is full
25
25
Click to add title
Guideline:
Check return statuses
26
26
Always check return status
e.g.,:
open a file for writing on a read-only file system;
fork() fails if process table is full
Fail safely
29
29
Click to add title
Guideline: Operate with least
privilege
30
30
Operate with least privilege
EUID: 0
RUID (unprivileged)
SUID (privileged)
General rules:
If EUID != 0, either:
setuid-root program:
seteuid(orig_euid)); /* Regain privileged EUID */
setuid(getuid()); /* Drop all privileged UIDs */
setuid-non-root program:
setreuid(getuid(), getuid()); /* Changes all UIDs */
set[ug]id()
set[ug]id()
http://userweb.kernel.org/~morgan/sendmail-capabilities-war-story.html
http://www.kernel.org/doc/man-pages/
credentials(7)
setuid(getuid()) is sufficient
Classic example:
For example:
Interactive input
Command-line arguments
User-supplied files
IPC channels
CGI inputs
Network packets
etc.
54
54
Don't trust user inputs! (cont.)
etc.
55
55
Don't trust user inputs! (cont.)
Classic example:
In this example:
Safest approach:
sigprocmask(2), signal(7)
Examples
Suppose we can:
Address-space randomization
Nonexecutable stacks
e.g., printf(argv[1]);
Use timeouts
Linux-specific...
76
76
Capabilities (cont.)
Further info:
Fail safely
Be aware of signals