Linux能力(capability)機制的繼承

来源:http://www.cnblogs.com/gordon0918/archive/2016/03/28/5328436.html
-Advertisement-
Play Games

1、Linux能力機制概述 在以往的UNIX系統上,為了做進程的許可權檢查,把進程分為兩類:特權進程(有效用戶ID是0)和非特權進程(有效用戶ID是非0)。特權進程可以通過內核所有的許可權檢查,而非特權進程的檢查則是基於進程的身份(有效ID,有效組及補充組信息)進行。 從linux內核2.2開始,Lin ...


1、Linux能力機制概述

在以往的UNIX系統上,為了做進程的許可權檢查,把進程分為兩類:特權進程(有效用戶ID是0)和非特權進程(有效用戶ID是非0)。特權進程可以通過內核所有的許可權檢查,而非特權進程的檢查則是基於進程的身份(有效ID,有效組及補充組信息)進行。

從linux內核2.2開始,Linux把超級用戶不同單元的許可權分開,可以單獨的開啟和禁止,稱為能力(capability)。可以將能力賦給普通的進程,使其可以做root用戶可以做的事情。

此時內核在檢查進程是否具有某項許可權的時候,不再檢查該進程的是特權進程還是非特權進程,而是檢查該進程是否具有其進行該操作的能力。例如當進程設置系統時間,內核會檢查該進程是否有設置系統時間(CAP_SYS_TIME)的能力,而不是檢查進程的ID是否為0;

當前Linux系統中共有37項特權,可在/usr/include/linux/capability.h文件中查看

2、Linux能力機制的實現

一個完整的能力機制需要滿足以下三個條件:

1、對進程的所有特權操作,linux內核必須檢查該進程該操作的特權位是否使能。

2、Linux內核必須提供系統調用,允許進程能力的修改與恢復。

3、文件系統必須支持能力機制可以附加到一個可執行文件上,但文件運行時,將其能力附加到進程當中。

到linux內核版本2.6.24為止,上述條件的1、2可以滿足。從linux內核2.6.24開始,上述3個條件可以都可以滿足

每個進程包括三個能力集,含義如下:

Permitted: 它是effective capabilities和Inheritable capability的超集。如果一個進程在Permitted集合中丟失一個能力,它無論如何不能再次獲取該能力(除非特權用戶再次賦予它)

Inheritable: 它是表明該進程可以通過execve繼承給新進程的能力。

Effecitive: Linux內核真正檢查的能力集。

從2.6.24開始,Linux內核可以給可執行文件賦予能力,可執行文件的三個能力集含義如下:

Permitted:該能力當可執行文件執行時自動附加到進程中,忽略Inhertiable capability。

Inheritable:它與進程的Inheritable集合做與操作,決定執行execve後新進程的Permitted集合。

Effective: 文件的Effective不是一個集合,而是一個單獨的位,用來決定進程成的Effective集合。

有上述描述可知,Linux系統中的能力分為兩部分,一部分是進程能力,一部分是文件能力,而Linux內核最終檢查的是進程能力中的Effective。而文件能力和進程能力中的其他部分用來完整能力繼承、限制等方面的內容。

3、Linux能力機制的繼承

在linux終端查看capabilities的man手冊,其中有繼承關係公式如下

      P'(permitted) = (P(inheritable) & F(inheritable)) |
                           (F(permitted) & cap_bset)              //新進程的permitted有老進程的和新進程的inheritable和可執行文件的permitted及cap_bset運算得到.
      P'(effective) = F(effective) ? P'(permitted) : 0            //新進程的effective依賴可執行文件的effective位,使能:和新進程的permitted一樣,負責為空
      P'(inheritable) = P(inheritable)    [i.e., unchanged]       //新進程的inheritable直接繼承老進程的Inheritable

      說明:

      P   在執行execve函數前,進程的能力
      P'  在執行execve函數後,進程的能力
      F   可執行文件的能力
      cap_bset 系統能力的邊界值,在此處預設全為1

有測試程式如下:

father.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/capability.h>
#include <errno.h>

void list_capability()
{
     struct __user_cap_header_struct cap_header_data;
     cap_user_header_t cap_header = &cap_header_data;

     struct __user_cap_data_struct cap_data_data;
     cap_user_data_t cap_data = &cap_data_data;

     cap_header->pid = getpid();
     cap_header->version = _LINUX_CAPABILITY_VERSION_1;

     if (capget(cap_header, cap_data) < 0) {
         perror("Failed capget");
         exit(1);
     }   
     printf("Cap data permitted: 0x%x,  effective: 0x%x,  inheritable:0x%x\n", 
         cap_data->permitted, cap_data->effective,cap_data->inheritable);
}

int main(void)
{
    cap_t caps = cap_init();
    cap_value_t capList[2] = {CAP_DAC_OVERRIDE, CAP_SYS_TIME};
    unsigned num_caps = 2;
    //cap_set_flag(caps, CAP_EFFECTIVE, num_caps, capList, CAP_SET);
    cap_set_flag(caps, CAP_INHERITABLE, num_caps, capList, CAP_SET);
    cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET);

    if(cap_set_proc(caps))
    {   
        perror("cap_set_proc"); 
    }   

    list_capability();

    execl("/home/xlzh/code/capability/child", NULL);

    sleep(1000);
}

child.c

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/capability.h>
#include <errno.h>

void list_capability()
{
     struct __user_cap_header_struct cap_header_data;
     cap_user_header_t cap_header = &cap_header_data;

     struct __user_cap_data_struct cap_data_data;
     cap_user_data_t cap_data = &cap_data_data;

     cap_header->pid = getpid();
     cap_header->version = _LINUX_CAPABILITY_VERSION_1;

     if (capget(cap_header, cap_data) < 0) {
         perror("Failed capget");
         exit(1);
     }
     printf("child Cap data permitted: 0x%x, effective: 0x%x, inheritable:0x%x\n", cap_data->permitted, cap_data->effective,cap_data->inheritable); 
}

int main(void)
{
    list_capability();
    sleep(1000);
}

執行結果分析

xlzh@cmos:~/code/capability$ gcc child.c -o child
xlzh@cmos:~/code/capability$ gcc father.c -o father -lcap
xlzh@cmos:~/code/capability$ sudo setcap cap_dac_override,cap_sys_time+ei child
xlzh@cmos:~/code/capability$ sudo setcap cap_dac_override,cap_sys_time+ip father
 /* 單獨執行,child文件有E(effective)I(inheritable)的能力,執行child的終端沒有任何能力, 套用公式(cap_bset預設全1)
  * P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)  // P'(permitted) = (0x0 & 0x2000002) | (0x0 & 全1),結果為0
  * P'(effective) = F(effective) ? P'(permitted) : 0                               // P'(effective) = 1 ? P'(permitted) : 0, 結果為P'(permitted),即0
  * P'(inheritable) = P(inheritable)                                               // P'(inheritable) = 0 
  * 執行結果如下所示
  */
xlzh@cmos:~/code/capability$ ./child 
child Cap data permitted: 0x0, effective: 0x0, inheritable 0x0
/* 單獨執行,child文件有E(effective)I(inheritable)的能力,執行child的father文件有E(inheritable)和P(permitted)能力, 套用公式
  * P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)  // P'(permitted) = (0x2000002 & 0x2000002) | (0x2000002 & 全1),結果為0
  * P'(effective) = F(effective) ? P'(permitted) : 0                               // P'(effective) = 1 ? P'(permitted) : 0, 結果為P'(permitted),即0x2000002
  * P'(inheritable) = P(inheritable)                                               // P'(inheritable) = 0x2000002
* 執行結果如下所示
  */
xlzh@cmos:~/code/capability$ ./father
father Cap data permitted: 0x2000002, effective: 0x0, inheritable: 0x2000002
child Cap data permitted: 0x2000002, effective: 0x2000002, inheritable 0x2000002

上述單獨運行child可執行程式,其進程沒有任何能力。但是有father進程來啟動運行child可執行程式,其進程則有相應的能力。

上例中father和child的能力都設置的cap_dac_override和cap_sys_time兩個能力。其實兩個可執行程式設置的能力可以不同,各位讀者可以自己修改其能力,套用公式進行計算。

4、以root用戶身份執行程式

1、以root用戶身份執行程式,則該進程所有能力的的P和I都置為1

2、以root用戶身份執行程式,則該進程的E使能

/*由於執行child的終端進程沒有I能力,所有child進程的inheritable也為0, 其他能力為全1*/
xlzh@cmos:~/code/capability$ sudo ./child 
child Cap data permitted: 0xffffffff, effective: 0xffffffff, inheritable 0x0

5、進程用戶ID的變化對能力的影響

1、當一個進程的有效用戶ID從0變化到非0, 那麼所有的E能力清零

2、當一個進程的有效用戶ID從非0變化到0,那麼現有的P集合拷貝到E集合

3、如果一個進行原來的真實用戶ID,有效用戶ID,保存設置用戶ID是0,由於某些操作這些ID都變成了非0,那麼所有的的P和E能力全部清理

4、如果一個文件系統的用戶ID從0變成非0,那麼以下的能力在E集合中清除:CAP_CHOWN, CAP_DAC_OVERRIDE,  CAP_DAC_READ_SEARCH,  CAP_FOWNER,  CAP_FSETID,  CAP_LINUX_IMMUTABLE  (since  Linux  2.2.30),  CAP_MAC_OVERRIDE,  CAP_MKNOD,如果一個文件系統的用戶ID從0變成非0,那麼在P集合中使能的能力將設置到E集合中。

 

參考:

man capabilities

http://www.cnblogs.com/iamfy/archive/2012/09/20/2694977.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.做訂閱發佈的2台Sql伺服器最好要版本一致,不能出現類似如下情況: Sql2008 R2[發佈] - Sql2008[訂閱]; Sql2008 R2[發佈] - Sql2012[訂閱] 2.訂閱發佈理論上必須 訂閱發佈資料庫 都要在 同一個 區域網,但也可以穿透區域網 嘗試實現以下, 資料: h ...
  • 主要講下redis的安裝配置,以及以服務的方式啟動redis 1.下載最新版本的redis-3.0.7 到http://redis.io/download中下載最新版的redis-3.0.7 下載後,將redis-3.0.7.tar.gz複製到虛擬機中目錄/home/lewis/dev_soft中 ...
  • sql_查詢select /****** Script for SelectTopNRows command from SSMS ******/ SELECT TOP 1000 [r_gonghao] ,[r_mingzi] ,[r_bumen] ,[r_xingbie] FROM [moge].[... ...
  • 一、基礎 源碼地址:http://www.jinhusns.com/Products/Download/?type=xcj 1.應用 1)、應用 tn_Applications 欄位名稱 欄位類型 可空 特殊 預設值 欄位描述 ApplicationId int no 主鍵 應用程式Id Appli ...
  • 創建一個表記員工個人信息: SQL> Table created 1 row inserted 1 row inserted 1 row inserted 1 row inserted 1 row inserted 1 row inserted 1 row inserted 1 row insert ...
  • 在保密你的伺服器和數據,防備當前複雜的攻擊,SQL Server有你需要的一切。但在你能有效使用這些安全功能前,你需要理解你面對的威脅和一些基本的安全概念。這篇文章提供了基礎,因此你可以對SQL Server里的安全功能充分利用,不用在面對特定威脅,不能保護你數據的功能上浪費時間。 SQL Serv ...
  • RabbitMQ是流行的開源消息隊列系統,是AMQP(Advanced Message Queuing Protocol高級消息隊列協議)的標準實現,用erlang語言開發。RabbitMQ據說具有良好的性能和時效性,同時還能夠非常好的支持集群和負載部署,非常適合在較大規模的分散式系統中使用,具體特 ...
  • 1、以root身份登陸CentOS依次 執行以下命令: wget https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz tar zxvf psutil-2.1.3.tar.gz cd psutil-2.1.3/ py ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...