【问题标题】:"Permission denied" in open() function in CC中open()函数中的“权限被拒绝”
【发布时间】:2020-01-05 18:16:53
【问题描述】:

我是 C 编程新手。我在使用 C 中的 open() 函数写入文件时遇到问题,为了清楚起见,这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

void usage(char *prog_name, char *filename){
    printf("Usage: %s <data to add to %s> \n",prog_name, filename);
    exit(0);
}

void fatal(char *);                          
void *errchck_malloc(unsigned int);     

int main(int argc, char *argv[]){
    int fd; // File descriptor
    char *buffer, *datafile;

    buffer = (char *) errchck_malloc(100);
    datafile = (char *) errchck_malloc(20);
    strcpy(datafile, "./simplenote.txt");

    if (argc < 2)
        usage(argv[0], datafile);

    strcpy(buffer, argv[1]);

    printf("[DEBUG] buffer @ %p: \'%s\'\n", buffer, buffer);
    printf("[DEBUG] datafile @ %p: \'%s\'\n", datafile, datafile);

    strncat(buffer, "\n", 1);

    // Open file 
    fd = open(datafile, O_CREAT|O_RDWR,O_APPEND, S_IRUSR, S_IWUSR);
    if(fd == -1)
        fatal("in main() while opening file");
    printf("[DEBUG] file descriptor is %d\n", fd);

    // Writing data to file
    if(write(fd, buffer, strlen(buffer))==-1)
        fatal("in main() while writing buffer to file");

    // Closing file
    if(close(fd) == -1)
        fatal("in main() while closing file");

    printf("Note saved\n");
    free(buffer);
    free(datafile);
}

// fatal(): Function to display error message then exit
void fatal(char *message){
    char err_msg[100];

    strcpy(err_msg, "[!!] Fatal Error ");
    strncat(err_msg, message, 83);
    perror(err_msg);
    exit(-1);
}

// errchck_malloc(): An error check malloc wrapper function
void *errchck_malloc(unsigned int size){
    void *ptr;
    ptr = malloc(size);
    if(ptr == NULL)
        fatal("in errchck_malloc() on memory allocation");
    return ptr;
}

当我第一次尝试执行程序时,程序按预期运行。

第一次运行:

user: ./simplenote "Hello, again"
[DEBUG] buffer @ 0x7fafcb4017a0: 'Hello again'
[DEBUG] datafile @ 0x7fafcb401810: './simplenote.txt'
[DEBUG] file descriptor is 3
Note saved

当我尝试打开文件并查看文本时,出现权限被拒绝错误。当我尝试使用 sudo 打开文件时,它会打开并且文本在文件中。当我第二次运行程序时,由于权限问题,打开文件时出现错误。

第二次运行:

user: ./simplenote "just checking if it is still working"                                                           
[DEBUG] buffer @ 0x7face4c017a0: 'just checking if it is still working'
[DEBUG] datafile @ 0x7face4c01810: './simplenote.txt'
[!!] Fatal Error in main() while opening file: Permission denied

如何解决文件创建的权限问题?

【问题讨论】:

  • open() 的参数不正确。我运行了代码,它创建了一个文件,其唯一权限是对组执行。这是后续执行出错的原因。
  • 这不是 jon ericson 的《剥削的艺术》一书中的代码吗?
  • @sf_admin 是的。谢谢
  • @Tijani 你应该写一些类似here is the code from the book "The art of exploit"的东西,但是当我尝试运行它时,我得到以下错误..而不是"here is my code"

标签: c file-access


【解决方案1】:

程序第一次运行时创建的文件具有不允许您追加的权限

stat simplenote.txt 
  File: simplenote.txt
  Size: 5           Blocks: 8          IO Block: 4096   regular file
Device: 2fh/47d Inode: 32810078    Links: 1
Access: (2000/------S---)  Uid: ( 1000/ user)   Gid: ( 1000/ user)
Access: 2020-01-05 19:29:34.317872734 +0100
Modify: 2020-01-05 19:29:34.317872734 +0100
Change: 2020-01-05 19:29:34.317872734 +0100

您应该像这样使用| 组合模式:

fd = open(datafile, O_CREAT|O_RDWR|O_APPEND, S_IRUSR | S_IWUSR);

您可以使用man open 检查应该传递给open 的参数,在我的系统上它会显示如下内容(修剪到重要部分):

   int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);

   int creat(const char *pathname, mode_t mode);

   int openat(int dirfd, const char *pathname, int flags);
   int openat(int dirfd, const char *pathname, int flags, mode_t mode);

【讨论】:

    【解决方案2】:

    open() 的参数不正确。 documentation of open() 说:

    int open(const char *pathname, int flags, mode_t mode);

    O_APPEND 是一个标志,它应该与其他两个进行或运算以产生flags 参数。

    S_IRUSRS_IWUSR 是权限。应该对它们进行 OR 运算以生成 mode 参数。

    总而言之,open() 的调用应该是:

    fd = open(datafile, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
    

    【讨论】:

    • 请注意,open() 是一个可变参数列表函数 (POSIX open())。它需要 2 或 3 个参数——当第二个包含 O_CREAT 并且需要创建文件时使用第三个。 OP 的代码传递 4 个参数。 open(const char *pathname, int flags, ...); 签名允许这样做(这就是没有关于第四个参数的编译器警告的原因),但忽略了额外的参数。
    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2023-03-03
    • 2013-04-21
    • 2020-11-02
    • 2018-06-11
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多