개발 · 컴퓨터공학 / / 2021. 10. 5. 20:34

UNIX - system call [umask, access, chmod, chown], file system[hark link, symbol link]

728x90
반응형

The file creation mask

안전장치 역할을 한다.

group과 others의 permission중 특정 bit들을 자동적으로 off 해준다.

유저가 임의로 특정 bit들을 on하는 것을 막기도 한다.

위 그림에서 mask는 group과 other의 write권한에 bit가 1로 세팅되어있다. 이와 같은 상황에서 mode의 bit와 mask의 bit를 bit wise and 연산한 결과로 permission을 할당한다.

filedesc = open(pathname, O_CREAT, mode)
filedesc = open(pathname, O_CREAT, (~mask) & mode)

mask는 default로 적용되어있으므로 위 코드에서 mask를 생략한 코드에서도 (~mask) & 가 있는 것과 같이 동작한다. 

umask(2)

#include <sys/stat.h>

mode_t umask(mode_t cmask);
// Returns: previous file mode creation mask

umask를 mask값을 변경할 수 있다. cmask 매개변수로 변경할 mask를 보내고,

return으로 변경 이전의 maks를 반환한다.

mask는 default로 022로 설정되어있다. 

 

umask(1) 명령어가 있어 다음과 같이 사용할 수 있다.

$ umask
$ umask -S
$ umask 22

example

예제 코드를 보자

#include <fcntl.h>
#include <sys/stat.h>

int specialcreat (const char *pathname, mode_t mode){
  mode_t oldu;
  int filedes:

  /* 화일 생성 마스크를 0으로 설정 */
  if ( (oldu = umask(0)) == ―1){
 	perror ("saving old mask");
 	return (-1);
  }

 /* 화일을 생성한다 */
 if((filedes=open(pathname, O_WRONLY|O_CREAT|O_EXCL, mode))== -1)
	 perror ("opening file");

 /* 비록 개방에 실패하더라도, 과거의 화일 모드를 복원한다. */
 if (umask (oldu) == -1) 
	 perror ("restoring old mask");

 /* 화일 기술자를 복귀한다. */
 return filedes;
}

 umask에 0값을 주어 mask를 0으로 설정하고 기존의 mask값을 oldu에 저장한다. mask를 0으로 설정했으므로 밑에서 파일을 생성할 때 mode의 permission은 그대로 적용된다.

저장했던 oldu값을 umask를 통해 설정함으로써 과거의 mode를 복원한다.

access(2)

#include <unistd.h>

int access(const char *pathname, int amode);
// Returns: 0 if OK,-1 on error

access system call은 real user 와 group id를 기반으로

매개변수로 주어진 pathname에 amode에 해당하는 permission이 주어졌는지를 체크한다. 

 

amode의 값은 다음과 같다

R_OK    test for read permission.
W_OK    test for write permission.
X_OK    test for execute permission.
F_OK    test for existence of file

amode 값으로 F_OK 설정하는 방법을 통해 파일의 존재여부도 알 수 있다. 

 

example

다음 예시 코드를 보자

/*access의 사용 예 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main()
{
  char *filename = "afile";

  if (access (filename, R_OK) == -1)
  {
 	fprintf (stderr, "User cannot read file %s\n", filename);
	exit (1);
  }
 
 printf ("%s readable, proceeding\n", filename);

  /* 프로그램의 나머지 부분... */
}

afile에 대해서 R_OK 즉 read 권한이 있는지를 access를 통해 체크한다.

 

chmod(2)

#include <unistd.h>

int chmod(const char *pathname, mode_t newmode);
// Returns: 0 if OK,-1 on error

command line의 chmod와 비슷한 역할이다.

pathname에 해당하는 파일을 newmode permission으로 설정한다. newmode 매개변수에는 permissoin 8진수가 들어간다.

chmod에서 파일에 접근하는 권한은 euid가 pathname의 file의 owner와 같으면 된다. 

 

아래 코드와 같이 권한을 변경할 수 있다.

if( chmod(pathname, 0644) == -1 )
    perror(“call to chmod failed”);

 

chown(2)

#include <unistd.h>

int chown(const char *pathname, uid_t owner_id, gid_t group_id);
//Returns: 0 if OK,-1 on error

command line의 chown과 비슷하다.

pathname에 해당하는 파일의 uid와 gid를 owner_id와 group_id를 통해 전달한 값으로 변경할 수 있다.

바꾸고 싶지 않은 값은 -1을 매개변수로 보내면 된다.

파일에 대한 권한이 없는데 chown으로 owner를 변경하려 하는 경우 EPERM에러를 띄운다. 

set-user-id와 set-group-id permission(r/w/x 이외 's' permission bit)은 ownership이 변경될 때 자동으로 off된다.

(set-user-id의 경우 user bit 'x'가 's'로, set-group-id의 경우 group bit 'x'가 'g'로 표시된다)

example

예를들어 다음 그림을 보자

A를 회사의 계정, spy는 스파이의 계정이라고 하자.

top secret에 접근하기 위한 파일 access top secret file은 내부적으로 보안처리가 되어있지만, 회사에서가 아닌 spy가 직접 만든 access top secret spy 파일을 's' 권한(set-user-id)으로 생성한 후 chown으로 access top secret spy 파일의 owner를 A로 변경해버리면 access top secret spy 파일을 A권한으로 실행하여 top secret에 접근할 수 있게되는 불상사가 발생한다. 

access top secret spy파일에 read write 권한으로 top secret을 열도록 하는 코드가 있다면 access top secret spy 파일을 통해 top secret을 마음대로 열어보고 변경도 가능하게 된다.

 

따라서 위와 같은 상황을 없애기 위해 chown을 실행할 때 's' 권한 bit를 자동적으로 off 해주는 것이다.

 

File with multiple names

file system

UNIX의 파일 시스템은 각 디렉토리들이 계층구조를 가지고 있다. 

mount-on

UNIX의 디렉토리는 루트 ('/')로부터 시작하는데, 다른 시스템을 연결할 때 디렉토리에 root를 붙이는 것을 mount라고 한다.

 

UNIX의 파일 시스템은 크게 4개의 block 으로 이루어져 있다.

Boot block

file system을 activate하는 boot code가 있는 곳

Super Block

파일 시스템의 다음과 같은 정보들을 담고 있다.

file system의 총 block 수
비어있는 inode의 수 
비어있는 block의 bit map
block의 byte size
채워져있는 block 수

data blocks

block단위로 데이터를 저자하는 곳

i - node

파일에 관한 정보들을 갖고 있으며, 어떤 파일이 있으면 해당 파일에 1:1로 대응되는 노드.

각 파일은 반드시 하나의 i-node와 대응하며, 디렉토리에서 파일의 이름이 disk의 어떤 파일을 가리키는지에 대한 포인터를 의미한다.

i-node의 번호 중 0번은 i-node가 없다는 의미로 사용된다. 1번은 bad disk block에 대한 정보를 가진 곳과 대응된다. 즉 2번부터 root 디렉토리를 시작으로 대응된다.

Hard link

hard link는 파일에 대한 direct pointer이다. 파일은 i-node와 1:1대응을 하지만 파일의 이름은 디렉토리에 저장되어있다. 디렉토리에서 각 파일의 이름에 대해서 i-node 주소가 연결되어있는 것인데, 이러한 연결을 hard link라고 한다.

 

 i-node에 연결된 파일이름의 개수를 link count라고 한다. link count가 0이 되면 해당 파일이름에 연결되어있는 i-node가 하나도 없는 것이므로 파일 삭제로 이어진다.

 서로 다른 파일 시스템을 mount 하는 경우 다른 파일 시스템에 있는 디렉토리에서 i-node를 hard link할 수 없다.

디렉토리를 추가하는 것은 권한이 허용된 어떤 사용자든 할 수 있지만, 같은 i-node에 대한 hard link를 추가하는 작업은 superuser만이 디렉토리에 대한 hard link를 만들 수 있다.

위 그림은 i-node와 파일 디렉토리에서 파일이름이 대응되는 것을 표현한 것인데, 위 그림의 오른쪽과 같이 i-node에 대응되는 파일이름이 추가되어 link count가 2 이상이되는 것은 superuser만이 할 수 있다.

 

Symbol link

윈도우 운영체제에서 '바로가기' 파일을 보면 해당 파일의 경로가 따로 있다. 다른 위치에 있는 파일이지만 pathname으로 지정된 파일을 가르키는 파일을 UNIX에선 Symbol link 라고 부른다. 

 symbol link는 연결된 파일에 대한 경로를 내용으로 담고 있으며, hard link와는 달리 다른 파일 시스템을 link할 수 있는 등 파일 시스템에 대한 제한이 없다. 

$ln –s /dirA/name1 /dirB/name2

위 명령어를 통해 서로 다른 파일 시스템 /dirA와 /dirB 사이에 symbol link가 되어있는 상황이다.

/dirB/name2 파일에 연결되어있는 data block의 내용에는 실제 데이터가 있는 파일의 경로 /dirA/name1을 담고 있기 때문에, 이 내용에 적인 경로를 찾아 가게된다. 

lrwxrwxrwx 1 root root Sep 10 07:14 name2 -> dirA/name1

symbol link는 permission bit 앞 file type에 'l'문자로 표시되며, '->' 기호로 가리키고 있는 original 파일을 나타낸다. 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유