0
votes

I saw the phenomenon that kernel panic appears after memcpy after mmap after resource0 ~ 4 file which is one of the sub files of /sys/devices/pci0000:00:xx.x.

At present, this phenomenon is found only in real physical servers, but not in environments like vm.

Is this a situation that can happen in this situation?

Are these special files not memory mapping to mmap?

When the read () function is called, errno 5 appears and the exception is processed. But, Mapping to mmap is not map_failed.

Is this behavior normal? If my application crashes, I do not know, but kernel panic appears and I ask.

Try a simple example source code

#include "errno.h"
#include "fcntl.h"
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stddef.h"
#include "sys/types.h"
#include "sys/mman.h"
#include "dirent.h"

int recursive_dir(char *dir);
int exec_file(char *file);

main(void) {

    // error 
    recursive_dir((char *)"/sys/devices");

    // not error 
//  recursive_dir((char *)"/tmp");
}

int recursive_dir(char *dir)
{
    DIR            *pdir = NULL;
    char           file[1024];
    struct stat    f_stat;
    struct dirent  entry, *result = NULL;

    if ( (pdir = opendir(dir)) == NULL) {
        printf("opendir(%s) fail.\n", dir);
        return -1;
    }

    while (readdir_r(pdir, &entry, &result) == 0 && result != NULL) {
        if (entry.d_ino == 0) {
            printf("[scan_dir] entry [%s].d_ino is 0. continue\n", entry.d_name);
            continue;
        }

        if (strcmp(entry.d_name, ".") == 0 ||
                strcmp(entry.d_name, "..") == 0) {
            continue;
        }

        if (strcmp(dir, "/") == 0) {
            snprintf(file, sizeof(file), "/%s", entry.d_name);
        } else {
            snprintf(file, sizeof(file), "%s/%s", dir, entry.d_name);
        }

        if (lstat(file, &f_stat) == -1) {
            continue;
        }

        if (S_ISLNK(f_stat.st_mode)) {
            printf("[%s] is symbolic link. continue\n", file);
            continue;
        } else if (S_ISDIR(f_stat.st_mode)) {
            recursive_dir(file);
        } else if (S_ISREG(f_stat.st_mode)) {
            exec_file(file);
        }
    }

    closedir(pdir);
    return 0;
}


int exec_file(char *file)
{
    int   my_offset = 0;
    char  data[101] = {0,};
    int   fd;
    int   len;
    void  *address;
    struct stat f_stat;

    // occurrence error file 
    //if ((fd = open("/sys/devices/pci0000:00/0000:00:1b.0/resource0", O_RDONLY)) == -1) {
    if ((fd = open(file, O_RDONLY)) == -1) {
        return -1;
    }

    if (lstat(file, &f_stat) == -1) {
        close(fd);
        return -1;
    }

    if ((len = f_stat.st_size) == 0) {
        close(fd);
        return -1;
    }
    printf("file [%s] size [%d]\n", file, len);

    my_offset = 0;

    memset(data, 0x00, sizeof(data));

    address =  mmap(NULL,
            len,
            PROT_READ,
            MAP_SHARED,
            fd,
            my_offset);

    if ( address != MAP_FAILED ) {
        memcpy(data, address, 100); /* copy memory */
    }

    munmap(address, len);
    close(fd);

    return 0;
}
1

1 Answers

0
votes

That is normal, some hardware changes state if read. Do not access those file unless you understand how the corresponding hardware acts, and how your change affects other software that is controlling the same hardware.