chapter8a

advertisement
系統程式
朱浩華教授/施吉昇教授
臺灣大學資訊工程系
Tei-Wei Kuo, Chi-Sheng Shih, and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Contents
1. Preface/Introduction
2. Standardization and Implementation
3. File I/O
4. Standard I/O Library
5. Files and Directories
6. System Data Files and Information
7. Environment of a Unix Process
8. Process Control
9. Signals
10. Inter-process Communication
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Multi-processes in modern systems
Image that you are now a system architect to
design a new multi-process systems.
Q1: How does the systems create a new process and
terminate a process?
Q2: What processes you need when the system starts?
Q2: Should you impose a communist or democratic
system on your system?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Process Control
Special Processes
PID 0 – Swapper (I.e., the scheduler)
Kernel process
No program on disks correspond to this
process
PID 1 – init responsible for bringing up a Unix
system after the kernel has been bootstrapped.
(/etc/rc* & init or /sbin/rc* & init)
User process with superuser privileges
PID 2 - pagedaemon responsible for paging
Kernel process
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Memory Management
Virtual Memory – Demand paging
Logical Memory
Memory Map
(Page Table)
Physical Memory
File System
Run
CPU
Swap-Out/In
Swap Space
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Memory Management
Virtual Memory – Demand paging
Memory
TLB
File System
Run
CPU
MMU
Logical
Address
Physical
Address
Swap-Out
Swap Space
Page
Table
Swap-In
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Memory Management
Demand Paging
Page fault -> disk I/O -> modify the page
table -> rerun the instruction!
Logical Address
P
Physical Address
D
F
P
Memory
D
F
Page
Table
page fault
disk I/O
File System /
Swap Space
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Process Control
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
None of them has an error return.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Discussion
How can your systems have multiple
processes?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
What’s a Fork()
Parent
If ((pid=fork()) == 0){
{
…
}
else {
}
exit(0);
Child
fork()
if ((pid=fork() == 0){
{
…
}
else {
}
exit(0);
Child is an exact copy of the parent process.
They have their own memory space.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
fork
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
The only way beside the bootstrap process
to create a new process.
Call once but return twice
0 for the child process (getppid)
Child pid for the parent (1:n)
Copies of almost everything but no sharing
of memory, except text
Copy-on-write (fork() – exec())
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
fork
Program 8.1 – Page 212
fork(), race conditions, write vs standard I/O
functions
File sharing
Sharing of file offesets (including stdin,
stdout, stderr)
Tables of
Opened Files
(per process)
System
Open File
Table
In-core
i-node
list
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
fork
Normal cases in fork:
The parent waits for the child to complete.
The parent and child each go their own way (e.g.,
network servers).
Inherited properties:
Real/effective [ug]id, supplementary gid, process group ID,
session ID, controlling terminal, set[ug]id flag, current working
dir, root dir, file-mode creation mask, signal mask & dispositions,
FD_CLOEXEC flags, environment, attached shared memory
segments, resource limits
Differences on properties:
Returned value from fork, process ID, parent pid, tms_[us]time,
tms_c[us]time, file locks, pending alarms, pending signals
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
fork
Reasons for fork to fail
Too many processes in the system
The total number of processes for the real uid
exceeds the limit
CHILD_MAX
Usages of fork
Duplicate a process to run different sections of code
Network servers
Want to run a different program
shells (spawn = fork+exec)
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
vfork
Design Objective
An optimization on performance
Execute exec right after returns from fork.
Mechanism – SVR4 & 4.3+BSD
Since 4BSD
<vfork.h> in some systems
No fully copying of the parent’s address space
into the child.
Sharing of address space
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
vfork
vfork() is as the same as fork() except
The child runs in the address space of its parent.
The parent waits until the child calls exit or exec.
Child process always executes first.
A possibility of deadlock if the child waits for the
parent to do something before calling exec().
Program 8.2 – Page 217
vfork,
_exit vs exit (flushing/closing of stdout)
exit() may close the file descriptors, causing printf() to
fail.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Deadlock – One Example
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Process Termination
Eight ways to terminate:
Normal termination
Return from main()
exit(main(argc, argv));
Call exit()
Call _exit() or _Exit()
Return of the last thread from its start routine
Calling pthread_exit from the last thread.
Abnormal termination (Chapter 10)
Call abort()
Be terminated by a signal
Response of the last thread to a cancellation request.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
exit
Termination
The same code in the kernel is finally
executed.
Close all open descriptors, release
memory, and the like.
Exit status vs. termination status
Exit status (arg from exit, _exit, or return)
 termination status
In abnormal case, the kernel generates it.
wait & waitpid to retrieve the termination
status.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Restarting point
Tei-Wei Kuo, Chi-Sheng Shih, and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Annoucements
Midterm exam scores are out
Average: 68.1
Std. Dev: 20.35
MP3 is out today
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Fun project #1
Hyperdragging (1999)
Dragging into the physical space
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Fun project #2
Diamond touch (2005)
Lay display flat on the table, and interactions
get interesting …
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Discussion
wait() and waitpid() are called by the
parent process to retrieve the
termination status of its child process.
Questions:
How to use these functions?
What if the child processes terminate before
wait() and waitpid() are called?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
wait & waitpid
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int op);
wait will block until one child terminates or an error
could be returned.
waitpid could wait for a specific one and has an
option not to be blocked.
SIGCHILD from the kernel if a child
terminates
Default action is ignoring.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
wait & waitpid
Three situations in calling wait/waitpid
Block
Return with the termination status of a child
Return with an error.
Termination Status <sys/wait.h> – Figure 8.4
Access termination status through the following MACROs
Exit status (WIFEXITED, WEXITSTATUS)
WIFEXITED(status): if successfully exited (true/false)
WEXITSTATUS(status): exit code
Signal # (WIFSIGNALED, WTERMSIG)
Core dump (WCOREDUMP)
Others (WIFSTOPPED, WSTOPSIG)
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Program 8.5 – Page 222
void
pr_exit(int status)
{
if (WIFEXITED(status))
printf("normal termination, exit status = %d\n",
WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number =
%d%s\n",
WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? " (core file
generated)" : "");
#else
"");
#endif
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %d\n",
WSTOPSIG(status));
}
linux1:~/sys_prog_06/test> fig.8.6.exe
normal termination, exit status = 7
abnormal termination, signal number = 6
abnormal termination, signal number = 8
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0)
exit(7);
if (wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0)
abort();
*/
if (wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0)
status /= 0;
SIGFPE */
if (wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
/* child */
/* wait for child */
/* and print its status */
/* child */
/* generates SIGABRT
/* wait for child */
/* and print its status */
/* child */
/* divide by 0 generates
/* wait for child */
/* and print its status */
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Zombie process
zombie
The process has terminated, but its parent
has not yet waited for it.
It keeps the minimal information for the
parent process.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
How is a Zombie process created?
Parent
If (pid=fork() == 0){
{
…
Child
fork()
If (pid=fork() == 0){
{
…
exit(0);
}
else {
// parent’s code
exit(0);
}
else {
// parent’s code
}
}
We get a zombie!!
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Cleaning up Zombies
What if the parent process terminates
before the child process?
Inherited by init
When a parent terminates, it is done by
the kernel.
Clean up of the zombies by the init – wait
whenever needed!
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Discussion: why do we need
zombie?
A parent process can end up with two
different children that share the same PID.
A parent process can end up trying to wait
for the return code of another process’s child.
If child process completely disappear, its parent
process won’t be able to wait on & fetch its
termination status.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
wait & waitpid
pid_t waitpid(pid_t pid, int *statloc, int op);
pid
pid == -1  wait for any child
pid > 0  wait for the child with pid
pid == 0  wait for any child with the same group id
pid < -1  wait for any child with the group ID = |pid|
return
pid of the child
0 if WNOHANG flag is set & the specified pid does not
exit
-1 an error is returned -> how can an error occur?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
wait & waitpid
Errors
No such child or wrong parent
Option for waitpid
WNOHANG, WUNTRACED
WNOWAIT, WCONTINUED (SVR4)
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Troubles from Zombie
Although Zombie processes do not occupy
any memory space in the system, it
consumes process IDs, which are limited
resources too.
You may not be able to fork new child
processes when there are too many zombie
processes in the systems.
CHILD_MAX: max number of simultaneous processes
per real user ID
How to fork a new child process but
not asking the parent process to wait for the child AND
not generating zombie process?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
How to create a background process
without making a zombie?
Parent
if (pid1=fork() == 0){
{
if (pid2=fork() == 0) {
}
else
exit(0);
}
else
waitpid(pid1, NULL, 0)
exit(0);
Child
if (pid1=fork() == 0){
{
if (pid2=fork() == 0) {
}
else
exit(0);
}
else
exit(0);
Grandchild
if (pid1=fork() == 0){
{
if (pid2=fork() == 0) {
sleep(2);
// grandchild exec
}
else
exit(0);
}
else
exit(0);
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
waitid
#include <sys/wait.h>
pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
Defined in XSI extension
Similar to waitpid() but provide extra info.
idtype:
P_PID: wait for a particular process
P_PGID: wait for a group of process
P_ALL: wait for any child process
options:
WCONTINUED
WNOHANG
WSTOPPED
WNOWAIT: the exit status will be kept for other wait()
functions.
WEXITED
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
wait3 & wait4 – resource usage info
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
pid_t wait3(int *statloc, int op, struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int op, struct rusage
*rusage);
4.3+BSD – Figure 8.4, Page 203
User/system CPU time, # of page faults, # of
signals received, the like.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Race Conditions
Def: When multiple processes are
trying to do something with shared
data, the final outcome depends on the
order in which the processes run.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Race condition example
A is the number of available copies
of a book = 1.
Two processes (transactions)
running concurrently.
Race between T1 & T2!
T1 wants to buy one copy.
T2 wants to buy one copy.
T1 gets an error.
T1
R(A=1)
Check if
(A>0)
The result is different from any serial
schedule T1,T2 or T2,T1
W(A=0)
Error!
How to solve this?
T2
R(A=1)
Check if
(A>0)
W(A=0)
Locking mechanism
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Another race condition example
Situation: T2 reads an object that has
been modified by T1, but T1 has not
committed.
T1 transfers $100 from A to B. T2 adds
6% interests to A and B. A nonserializable schedule is:
T1
R(A)
W(A-100)
R(A)
W(A+6%)
Step 1: deduct $100 from A.
Step 2: add 6% interest to A & B.
Step 3: credit $100 in B.
R(B)
W(B+6%)
Why is the problem?
The result differs based on different order of
execution
The result differs from any serial schedule > Bank adds $6 less interest.
T2
Commit
R(B)
W(B+100)
Commit
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Race Conditions
Example: Program 8.8 – Page 225
Who is the parent of the 2nd child?
Program 8.12 – Page 229
Mixture of output by putc + setting of
unbuffering for stdout
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Can you spot the potential race condition?
(avoid zombie processes by calling fork twice)
if (waitpid(pid, NULL, 0) != pid)
/* wait for first child */
err_sys("waitpid error");
int
main(void)
{
pid_t pid;
/*
* We're the parent (the original
process); we continue executing,
* knowing that we're not the
parent of the second child.
*/
exit(0);
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {
/* first child */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0);
/* parent from second fork == first child */
}
/*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d\n", getppid());
exit(0);
}
What if the 2nd child exit
before the 1st child
called exit(0)?
- parent of 2nd child is
not init by the 1st child.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Race Conditions
How to synchronize parent and child
processes?
Busy wait?
while (getppid() != 1)
sleep(1);
Waste CPU time, other means possible: InterProcess Communication facility, such as pipe fifo,
semaphore, shared memory, etc.
Program 8.13 on Page 206
WAIT_PARENT(), TELL_CHILD(), WAIT_CHILD(),
TELL_PARENT()
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Can you spot the potential race condition?
(avoid zombie processes by calling fork twice)
if (waitpid(pid, NULL, 0) != pid)
/* wait for first child */
err_sys("waitpid error");
int
main(void)
{
pid_t pid;
/*
* We're the parent (the original
process); we continue executing,
* knowing that we're not the
parent of the second child.
*/
exit(0);
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {
/* first child */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0);
/* parent from second fork == first child */
}
/*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d\n", getppid());
while (getppid() != 1)
sleep(1);
exit(0);
What if the 2nd child exit
before the 1st child
called exit(0)?
- parent of 2nd child is
not init by the 1st child.
}
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Can you spot the potential race condition?
Program 8.12 on page 229
$ ./a.out
ooutput from child
utput from parent
static void charatatime(char *);
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {
charatatime("output from child\n");
} else {
charatatime("output from parent\n");
}
exit(0);
$ ./a.out
output from child
output from parent
}
static void charatatime(char *str)
{
char *ptr;
int
c;
setbuf(stdout, NULL);
for (ptr = str; (c = *ptr++) != 0; )
putc(c, stdout);
/* set unbuffered */
}
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Avoid race condition
#include <sys/types.h>
#include "ourhdr.h"
static void charatatime(char *);
int
main(void)
{
pid_t pid;
TELL_WAIT();
if ( (pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) {
WAIT_PARENT(); // parent goes first
charatatime("output from child\n");
} else {
charatatime("output from parent\n");
TELL_CHILD(pid);
}
exit(0);
}
static void charatatime(char *str)
{
… …
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
}
Graduate institute of Multimedia and Networking, National Taiwan University
exec (6 variations)
Replace the text, data, heap, and stack segments of a
process with a program!
Specify: new program, command line args, environment
#include <unistd.h>
int execl(const char *pathname, const char *arg0, … /* (char *)
0 */);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, … /* (char
*) 0, char *const envp[] */);
int execve(const char *pathname, char *const argv[], char
*const envp[]);
int execlp(const char *filename, const char *arg0, … /* (char *)
0 */);
int execvp(const char *filename, char *const argv[]);
What do l, v, e, and p stand for?
What one is the most general one?
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
exec
l, v, and e stands for list, vector, and environment,
respectively.
command-line arg must end with null pointer
Limit on # of command line args: ARG_MAX
With p, a filename is specified unless it contains ‘/’.
PATH=/bin:/usr/bin:.
/bin/sh is invoked with “filename” if the file is not
a machine executable.
When do you want to change environ parameters?
login process
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
exec
Inherited from the calling process:
pid, ppid, real [ug]id, supplementary gid, proc gid,
session id, controlling terminal, time left until alarm
clock, current working dir, root dir, file mode creation
mask, file locks, proc signal mask, pending signals,
resource limits, tms_[us]time, tms_cutime,
tms_ustime
FD_CLOEXEC flag
Requirement
Closing of open dir streams
May change:
effective user/group ID if new program has set-uidID bit set
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
exec
execlp
execl
build argv
build argv
execvp
execle
try each
PATH prefix
execv
use
environ
build argv
execve
In many Unix implementations, execve()
is a system call, other exec are library
functions calling execve().
Program 8.8 – Page 235
Program 8.9 – Page 236
The prompt bet the printing of argv[0] and argv[1].
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
exec example
char
*env_init[] = { "USER=unknown",
"PATH=/tmp", NULL };
int
main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* specify pathname, specify environment */
if
(execle("/mnt/professor/hchu/sys_p
rog_06/test/fig8.17.exe", "echoall",
"myarg1", "MY ARG2", (char *)0,
env_init) < 0)
err_sys("execle error");
}
if (waitpid(pid, NULL, 0) < 0)
err_sys("wait error");
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* specify filename, inherit environment */
if (execlp("fig8.17.exe",
"echoall", "only 1 arg", (char *)0) <
0)
err_sys("execlp error");
linux1:~/sys_prog_06/test> fig8.16.exe
argv[0]: echoall
argv[1]: myarg1
argv[2]: MY ARG2
USER=unknown
PATH=/tmp
linux1:~/sys_prog_06/test> argv[0]: echoall
argv[1]: only 1 arg
USER=hchu
LOGNAME=hchu
HOME=/home/professor/hchu
PATH=/usr/bin:/bin:/usr/X11R6/bin:/opt/kde/bin:.
MAIL=/var/mail/hchu
SHELL=/bin/tcsh
SSH_CLIENT=140.112.30.82 46314 22
SSH_CONNECTION=140.112.30.82 46314
140.112.30.32 22
SSH_TTY=/dev/pts/5
TERM=xterm
DISPLAY=localhost:10.0
LANG=zh_TW.Big5
HOSTTYPE=i486-linux
VENDOR=intel
OSTYPE=linux
MACHTYPE=i486
SHLVL=1
PWD=/home/professor/hchu/sys_prog_06/test
GROUP=users
HOST=linux1
REMOTEHOST=dhcp1.csie.ntu.edu.tw
LC_ALL=zh_TW.Big5
}
exit(0);
}
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
program 8.17
#include "apue.h"
int
main(int argc, char *argv[])
{
int
i;
char
**ptr;
extern char **environ;
for (i = 0; i < argc; i++)
/* echo all command-line args */
printf("argv[%d]: %s\n", i, argv[i]);
for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */
printf("%s\n", *ptr);
exit(0);
}
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Changing User/Group ID’s
This part is confusing … (when I read it)
Why changes user id in the middle of a
program execution?
Least-privilege model: a program should use the least
privilege necessary to accomplish any task.
Reduce window of security vulnerability
Example: a process needs to gain a privilege to
access a privileged file
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Recall …
A process can have more than one ID.
Real user/group ID: who you really are
Effective user/group ID: determine file access
permission
Supplementary group IDs
Saved set-user/group-ID = owner of the
program with set-user-id bit set
Why do you need saved set-user-id?
cannot give up privilege temporarily (and get it back)
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Recall …
#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
The process == superuser  set real/effective/saved-suid = uid
Otherwise, euid=uid if uid == ruid or uid == saved-suid (suid =
set-uid)
Return 0 upon success
Return -1 otherwise, errno=EPERM (_POSIX_SAVED_IDS)
int setgid(gid_t gid);
The same as setuid
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
User/Group ID’s
Only superuser process can change the real
uid – normally done by the login program.
The euid is set by exec only if the setuid bit is
set for the program file. euid can only be set
as its saved-suid or ruid.
exec copies the euid to the saved-suid (after
the setting of euid if setuid bit is on).
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
User/Group ID’s
Example man program
man is used for displaying manual pages
The setuid bit is on for man (owner=man).
For file locking
man calls setuid(ruid) for privileged file access
on some configuration file
Correct uid
Switch the euid back to man after it is done
with them
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Example of using setuid()
Real user ID = Our user ID
Step 1: exec tip program:
Effective user ID = man
Saved-set-user ID = man
Step 2: access the required
locks
Step 3: setuid(getuid()) to
return to normal permission
Step 4: calling setuid(uucpuid)
to change the effective user
ID
Real user ID = Our user ID
Effective user ID = Our user ID
Saved-set-user ID = man
Real user ID = Our user ID
Effective user ID = Man
Saved-set-user ID = man
Step 5: release the lock.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
User/Group ID’s
#include <sys/types.h>
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(uid_t rgid, uid_t egid);
Change both ruid/rgid and euid/egid.
Swapping of real and effective uids.
Good for even unprivileged users.
BSD only or BSD-compatibility library
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
User/Group ID’s
#include <sys/types.h>
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(uid_t gid);
Change only euid/egid.
Non-superusers can only set euid=ruid or savedsetuid.
A privileged user only sets euid = uid.
It is different from setuid(uid)
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
User/Group ID’s
superuser
setreuid(ruid, euid)
euid
ruid
real uid
superuser
setuid(uid)
uid
nonsuperuser
setreuid
nonsuperuser
setuid or seteuid
superuser
seteuid(uid)
uid
uid
effective uid
nonsuperuser
setreuid
uid
saved suid
exec of suid
nonsuperuser
setuid or seteuid
The supplementary guid’s are not
affected by the setgid function.
Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006
Department of Computer Science and Information Engineering
Graduate institute of Multimedia and Networking, National Taiwan University
Download