欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

linux可執(zhí)行文件與寫(xiě)操作的同步問(wèn)題怎么解決

這篇文章主要介紹“l(fā)inux可執(zhí)行文件與寫(xiě)操作的同步問(wèn)題怎么解決”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“l(fā)inux可執(zhí)行文件與寫(xiě)操作的同步問(wèn)題怎么解決”文章能幫助大家解決問(wèn)題。

創(chuàng)新互聯(lián)是一家專業(yè)提供郫都企業(yè)網(wǎng)站建設(shè),專注與做網(wǎng)站、網(wǎng)站制作H5響應(yīng)式網(wǎng)站、小程序制作等業(yè)務(wù)。10年已為郫都眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

inode結(jié)點(diǎn)中包含一個(gè)數(shù)據(jù)項(xiàng),叫做i_writecount,很明顯是用于記錄文件被寫(xiě)的個(gè)數(shù)的,用于同步的,其類型也是atomic_t. 內(nèi)核中有兩個(gè)我們需要了解的函數(shù),與write操作有關(guān),分別是:

復(fù)制代碼 代碼如下:

int get_write_access(struct inode * inode)
{
    spin_lock(&inode->i_lock);
    if (atomic_read(&inode->i_writecount) < 0) {
                spin_unlock(&inode->i_lock);
        return -etxtbsy;
    }
    atomic_inc(&inode->i_writecount);
        spin_unlock(&inode->i_lock);
    return 0;
}

int deny_write_access(struct file * file)
{
    struct inode *inode = file->f_path.dentry->d_inode;
        spin_lock(&inode->i_lock);
    if (atomic_read(&inode->i_writecount) > 0) {//如果文件被打開(kāi)了,返回失敗
                spin_unlock(&inode->i_lock);
        return -etxtbsy;
    }
        atomic_dec(&inode->i_writecount);
    spin_unlock(&inode->i_lock);
}

這兩個(gè)函數(shù)都很簡(jiǎn)單,get_write_acess作用就和名稱一致,同樣deny_write_access也是。如果一個(gè)文件被執(zhí)行了,要保證它在執(zhí)行的過(guò)程中不能被寫(xiě),那么在開(kāi)始執(zhí)行前應(yīng)該調(diào)用deny_write_access 來(lái)關(guān)閉寫(xiě)的權(quán)限。那就來(lái)檢查execve系統(tǒng)調(diào)用有沒(méi)有這么做。
sys_execve中調(diào)用do_execve,然后又調(diào)用函數(shù)open_exec,看一下open_exec的代碼:

復(fù)制代碼 代碼如下:

struct file *open_exec(const char *name)
{
    struct file *file;
    int err;
        file = do_filp_open(at_fdcwd, name,
                o_largefile | o_rdonly | fmode_exec, 0,
                may_exec | may_open);

        if (is_err(file))
        goto out;
        err = -eacces;

    if (!s_isreg(file->f_path.dentry->d_inode->i_mode))
        goto exit;

        if (file->f_path.mnt->mnt_flags & mnt_noexec)
        goto exit;

        fsnotify_open(file->f_path.dentry);
    err = deny_write_access(file);//調(diào)用
       if (err)
        goto exit;

       out:
    return file;

       exit:
    fput(file);
    return err_ptr(err);
}

明顯看到了deny_write_access的調(diào)用,和預(yù)想的完全一致。在open的調(diào)用里,應(yīng)該有g(shù)et_write_access的調(diào)用。在open調(diào)用相關(guān)的__dentry_open函數(shù)中就包含了對(duì)該函數(shù)的調(diào)用。

復(fù)制代碼 代碼如下:


if (f->f_mode & fmode_write) {
    error = __get_file_write_access(inode, mnt);
    if (error)
            goto cleanup_file;
    if (!special_file(inode->i_mode))
      file_take_write(f);
}


其中__get_file_write_access(inode, mnt)封裝了get_write_access.
那么內(nèi)核又是如何保證一個(gè)正在被寫(xiě)的文件是不允許被執(zhí)行的呢?這個(gè)同樣也很簡(jiǎn)單,當(dāng)一個(gè)文件已經(jīng)為write而open時(shí),它對(duì)應(yīng)的inode的i_writecount會(huì)變成1,因此在執(zhí)行execve時(shí)同樣會(huì)調(diào)用deny_write_access 中讀取到i_writecount>0之后就會(huì)返回失敗,因此execve也就會(huì)失敗返回。
這里是寫(xiě)文件與i_writecount相關(guān)的場(chǎng)景:
寫(xiě)打開(kāi)一個(gè)文件時(shí),在函數(shù)dentry_open中:

復(fù)制代碼 代碼如下:


if (f->f_mode & fmode_write) {
    error = get_write_access(inode);
    if (error)
    goto cleanup_file;
}


當(dāng)然在文件關(guān)閉時(shí),會(huì)將i_writecount--;關(guān)閉時(shí)會(huì)執(zhí)行代碼:

復(fù)制代碼 代碼如下:


if (file->f_mode & fmode_write)
    put_write_access(inode);


put_write_access 代碼很簡(jiǎn)單:

復(fù)制代碼 代碼如下:


static inline void put_write_access(struct inode * inode)
{
    atomic_dec(&inode->i_writecount);
}

于是乎自己寫(xiě)了個(gè)簡(jiǎn)單的代碼,一個(gè)空循環(huán),文件在執(zhí)行的時(shí)候,在bash中,echo 111 >>可執(zhí)行文件,結(jié)果預(yù)期之中,返回失敗,并提示信息 text file busy.
那么該機(jī)制是否同樣適用于映射機(jī)制呢,在執(zhí)行可執(zhí)行文件時(shí),會(huì)mmap一些關(guān)聯(lián)的動(dòng)態(tài)鏈接庫(kù),這些動(dòng)態(tài)鏈接庫(kù)是否被mmap之后就不允許被寫(xiě)以及正在寫(xiě)時(shí)不允許mmap呢?這個(gè)是需要考慮的,因?yàn)樗P(guān)系到安全的問(wèn)題。因?yàn)閹?kù)文件也是可執(zhí)行的代碼,被篡改同樣會(huì)引起安全問(wèn)題。
mmap在調(diào)用mmap_region的函數(shù)里,有一個(gè)相關(guān)的檢查:

復(fù)制代碼 代碼如下:


if (vm_flags & vm_denywrite) {         
        error = deny_write_access(file);
    if (error)
        goto free_vma;
    correct_wcount = 1;
}


其中,mmap調(diào)用中的flags參數(shù)會(huì)被正確的賦值給vm_flags,對(duì)應(yīng)關(guān)系是map_denywrire被設(shè)置了,那么vm_denywrite就對(duì)應(yīng)的也被設(shè)置。下面寫(xiě)了個(gè)簡(jiǎn)單的代碼,做一下測(cè)試:

復(fù)制代碼 代碼如下:


#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
        int fd;
    void *src = null;
    fd = open("test.txt",o_rdonly);
    if (fd != 0)
        {
        if ((src = mmap(0,5,prot_read|prot_exec  ,map_private|        map_denywrite,fd,0))== map_failed)
                {
            printf("mmap error\n");
            printf("%s\n",strerror(errno));
                }else{
            printf("%x\n",src);
        }
    }

        file * fd_t = fopen("test.txt","w");
    if( !fd_t)
    {
                printf("open for write error\n");
        printf("%s\n",strerror(errno));
        return 0;
    }

        if (fwrite("0000",sizeof(char),4,fd_t) != 4)
    {
        printf("fwrite error \n");
    }

     
        fclose(fd_t);
    close(fd);
    return 1;
}


最后的test.txt被寫(xiě)成了”0000”,很奇怪,貌似map_dentwrite不起作用了。于是man mmap查看,發(fā)現(xiàn):

map_denywrite

this  flag  is ignored.  (long ago, it signaled that attempts to write to the underlying file should fail with etxtbusy. but this was a source of denial-of-service attacks.)

原來(lái)這個(gè)標(biāo)識(shí)在用戶層已經(jīng)不起作用了啊,而且還說(shuō)明了原因,容易引起拒絕式服務(wù)攻擊。攻擊者惡意的將某些系統(tǒng)程序要寫(xiě)的文件以map_denywrite模式映射,會(huì)導(dǎo)致正常程序?qū)懳募 2贿^(guò)vm_denywrite在內(nèi)核里還是有使用的,在mmap中還是有對(duì)deny_write_access的調(diào)用, 但是對(duì)它的調(diào)用已經(jīng)不是由mmap中的flag參數(shù)的map_denywrite驅(qū)動(dòng)的了。

關(guān)于“l(fā)inux可執(zhí)行文件與寫(xiě)操作的同步問(wèn)題怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

分享文章:linux可執(zhí)行文件與寫(xiě)操作的同步問(wèn)題怎么解決
文章路徑:http://chinadenli.net/article2/iphhic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管網(wǎng)頁(yè)設(shè)計(jì)公司App設(shè)計(jì)網(wǎng)站維護(hù)建站公司網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)