文档章节

Credentials and Access Control in Linux

ChenQi
 ChenQi
发布于 2017/05/31 14:59
字数 1432
阅读 19
收藏 0

Credentials and Access Control in Linux
=======================================

File ower and permission [important]
------------------------------------
File mode (permission), user ID and group ID are contained in the corresponding
inode of the file.
An inode at least contains the following members:
   *) size
   *) device ID (the device containing the file)
   *) user ID
   *) group ID
   *) file mode
   *) timestamp
   *) link count (number of hard links)
   *) pointers to the disk blocks
A direct deduction of the above statement is that if a file changes (content,
timestamp, user ID, group ID, file mode, etc.), all hardlinks pointint to it
also changes, as all these hard links share a common inode.


Process Credentials [important]
-------------------------------
Process Identifers:
*) process ID
*) parent process ID
*) process group ID
*) session ID
*) real user ID   | who owns the process
*) real group ID  |
*) effective user ID  |used by kernel for access control to shared resources
*) effective group ID |such as message queues, semaphores, etc.)
*) file system user ID  | together with supplementary group IDs, used to
*) file system group ID | determine permissions for accessing files
*) supplementary group ID | used for permission checks for accessing files
*) saved set-user-ID  | used to save a copy of corresponding effective IDs when
*) saved set-group-ID | the process was executed


Related System Calls [important]
--------------------------------
*) getpid
   Get process ID

*) getppid
   Get parent process ID

*) getsid
   Get session ID

*) getpgrp
   Get process group ID

*) setsid
   Create a new session. The calling process becomes the session leader.

*) setpgid
   Set process's group membership

*) getuid
   Get the process's real user ID

*) setuid
   If the caller is not root, setuid sets the effective user ID of the calling
   processs; if the caller is root, setuid also sets the real user ID and the
   saved user ID.

*) seteuid
   Set the effective user ID of the calling process. An unprivileged user
   process could only set the effective user ID to real user ID, effective
   user ID and saved user ID.

*) setfsuid
   Set a process's file system user ID. It's used to make the file system user
   ID to differ from the process's effective user ID.

*) setreuid
   Set real and effective user ID.

*) getgid
   Get the process's real group ID.

*) getegid
   Set effective group ID.

*) getresgid
   Get real, effective and saved group ID.

*) setgid
   Completely analogous to  setuid.

*) setregid
   Set real and effective group ID.

*) setfsgid
   Set file system group ID.

*) getgroups
   Get supplementary group IDs of a process

*) setgroups
   Set supplementary group IDs of a process

*) setresuid
   Set real, effective and saved user ID.

*) setresgid
   set real, effective and saved group ID.


Potential problem with suid programs [important]
------------------------------------------------
suid programs have potential security problems if not well programmed.

E.g.
User 'chenqi' doesn't have read permission for /etc/shadow, but if a program
owned by root has set-user-ID bit and it could be executed by 'chenqi', then
it's possible that the user 'chenqi' can make use of the setuid program to get
the contents of /etc/shadow.

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ cat test.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef MAXLINE
#define MAXLINE 4096
#endif

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "%s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL) {
        perror("open file failed");
        exit(EXIT_FAILURE);
    }
    char buf[MAXLINE];
    while (fgets(buf, MAXLINE, fp) != NULL) {
        if (fputs(buf, stdout) == EOF) {
            perror("output error");
            exit(EXIT_FAILURE);
        }
    }
    if (fp != NULL)
        fclose(fp);
    exit(EXIT_SUCCESS);
}

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ls -l test
-rwsr-sr-x 1 root root 8774 Oct 12 15:37 test

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ cat /etc/shadow
cat: /etc/shadow: Permission denied

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ./test /etc/shadow
root:<encrypted passwd for root>:15555:0:99999:7:::
daemon:*:15455:0:99999:7:::
bin:*:15455:0:99999:7:::
<the rest of the contents omitted>

It's not quite straightforward that the above program is poorly programmed,
providing that the programmer knows that the program will be made suid
One possible way to address the above problem is to temporarily drop privilege
to real user ID when opening the file.

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ls test -l
-rwsr-sr-x 1 root root 9156 Oct 12 16:01 test

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ./test test.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef MAXLINE
#define MAXLINE 4096
#endif

static void xseteuid(uid_t euid) {
    if (seteuid(euid)) {
        perror("seteuid");
        exit(EXIT_FAILURE);
    }
}

static void xsetegid(gid_t egid) {
    if (setegid(egid)) {
        perror("setegid");
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "%s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    uid_t old_euid = geteuid();
    gid_t old_egid = getegid();
    xseteuid(getuid());
    xsetegid(getgid());
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL) {
        perror("open file failed");
        exit(EXIT_FAILURE);
    }
    xseteuid(old_euid);
    xsetegid(old_egid);
    char buf[MAXLINE];
    while (fgets(buf, MAXLINE, fp) != NULL) {
        if (fputs(buf, stdout) == EOF) {
            perror("output error");
            exit(EXIT_FAILURE);
        }
    }
    if (fp != NULL)
        fclose(fp);
    exit(EXIT_SUCCESS);
}

chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ./test /etc/shadow
open file failed: Permission denied


Q & A [important]
-----------------
1. If the euid of a process is not zero (superuser), is it possible for
   the program to change its euid to zero and gain privilege?

   It depends. If the saved uid is zero, the answer is yes. Because the seteuid
   system call could set the effective uid to only the real uid or saved uid.
   Note the case above usually indicates that a process has dropped its
   privilege temporarily and it's trying to restore its privilege.

2. (r, e, s) = (x, x, 0) where x != 0, is it possible to change (r, e, s) to
   (0, x, 0) using setresuid()? What about using setreuid()?

   Both can. The setreuid() user manual is not accurate. It states as follows.
   "Unprivileged users may only set the real user ID to the real user ID or the
   effective user ID."
   However, for an unprivileged user, the real user ID could be set to the saved
   user ID.
   e.g.
   chenqi@pek-qchen1-d1:~/projects/mypro/linux/miscs$ ./test
   16079: (1000, 0, 0)
   16079: (1000, 1000, 0)
   16079: (0, 1000, 0)

3. Is it possible to clear the SETUID capability bit in a process whose
   effective uid is zero?

   No. The kernel has fixed this bug.


Notes [important]
-----------------
1. We need to know that user privilege and process privilege are two different
   things. The user privilege is determined by the real user ID of the process,
   i.e., the owner of the process; the process privilege is determined by the
   effective user ID of the process.

2. The execute permission bit of a diretory is often called the search bit, as
   whenever we want to open any type of file by name, we must have execute
   permission in each directory mensioned in the name. That's why the default
   permission of a directory is 0775(rwxrwxr-x) or 0755(rwxr-xr-x).

3. Read permission of a directory and execute permission of a directory
   Read permission for a directory lets us read the directory, obtaining a list
   of all filenames in the directory.
   Execute permisssion lets us pass through the directory when it is a component
   of a pathname that we are trying to access.
   e.g.
   chenqi@chenqi-Vostro-2420:~/tests$ stat foo/ | grep 'Access: ('
   Access: (0775/drwxrwxr-x)  Uid: ( 1001/  chenqi)   Gid: ( 1001/  chenqi)
   chenqi@chenqi-Vostro-2420:~/tests$ chmod o-r foo/
   chenqi@chenqi-Vostro-2420:~/tests$ su lfs
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ ls foo/
   ls: cannot open directory foo/: Permission denied
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ ls foo/bar
   1
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ cat foo/bar/1
   hello  world
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ exit
   exit
   chenqi@chenqi-Vostro-2420:~/tests$ chmod o+r foo/
   chenqi@chenqi-Vostro-2420:~/tests$ chmod o-x foo/
   chenqi@chenqi-Vostro-2420:~/tests$ stat foo/ | grep 'Access: ('
   Access: (0774/drwxrwxr--)  Uid: ( 1001/  chenqi)   Gid: ( 1001/  chenqi)
   chenqi@chenqi-Vostro-2420:~/tests$ su lfs
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ ls foo/
   bar
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ ls foo/bar
   ls: cannot access foo/bar: Permission denied
   lfs@chenqi-Vostro-2420:/home/chenqi/tests$ cat foo/bar/1
   cat: foo/bar/1: Permission denied

4. The kernel perform access tests using the file's st_uid and st_gid and the
   effective user and group IDs. However, there are times when a process wants
   to test accessiility based on the real user and group IDs.
   The access function bases its tests on the real user and group IDs.
   So it's possible that access to a file fails but open that file succeeds.
   This happens when the real user ID is, for example, chenqi, and the effective
   user ID is root, and the permission of the file is 0400.

© 著作权归作者所有

ChenQi
粉丝 61
博文 191
码字总数 111579
作品 0
丰台
高级程序员
私信 提问

暂无文章

HashMap源码分析

read

V丶zxw
34分钟前
4
0
Python字符串或JSON字符串转字典dict、列表list

有3种方法 1、使用ast模块 >>> import ast>>> s = '["test",1]'>>> ast.literal_eval(s)['test',1]>>> s = '{"test":1}'>>> ast.literal_eval(s){'test': 1} 2、eval函数,这个......

编程老陆
52分钟前
5
0
【JS复习笔记】03 继承(从ES5到ES6)

本文转载于:专业的前端网站➫【JS复习笔记】03 继承(从ES5到ES6) 前言 很久以前学习《Javascript语言精粹》时,写过一个关于js的系列学习笔记。 最近又跟别人讲什么原型和继承什么的,发现...

前端老手
55分钟前
8
0
简单动态网站搭建

如何在windows服务器上配置wordPress和discuz 网站建设中的概念讲解 网站建设的基础操作 网站程序的基础使用 网站程序的优化 简单动态网站搭建 软件部署 域名和主机的购买 域名解析 环境部署...

达达前端小酒馆
今天
6
0
Java每日面试题_03

15、构造器是否可被override constructor(构造器)不能被继承,所以不能被override(重写),但是可以被overloading(重载)。 16、抽象类和接口的区别 抽象类是什么 含有abstract修饰符的class即...

庭前云落
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部