~aleteoryx/muditaos

ref: e8d1fd23a378169c85a6b9be7e21221ccf04eea0 muditaos/board/linux/libiosyscalls/src/iosyscalls.cpp -rw-r--r-- 5.0 KiB
e8d1fd23 — Wiktor S. Ovalle Correa [EGD-5177] Change iosyscalls code style 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <iosyscalls.hpp>
#include <cstdlib>
#include <cstring>
#include <pthread.h>
#include <parallel_hashmap/phmap.h>
#include <stdio.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <debug.hpp>
#include <dirent.h>

namespace {
    constexpr auto ENV_NAME = "IOSYSCALLS_REDIRECT_TO_IMAGE";
    constexpr auto FIRST_FILEDESC = 64'566'756;
    bool g_readed = false ;
    bool g_redirect = false;
    constexpr const char * ALLOWED_PATHS[] = {
        "/dev/",
        "/etc/",
        "/sys/",
        "/usr/share",
        "/run/user",
        "/home",
        "/proc",
        "/dev/shm",
        "PurePhone.img",
        nullptr,
    };
    constexpr const char * EXCLUDED_PATHS[] = {
        "/sys/user",
        "/sys/factory-test",
        "/sys/current/assets",
        "/sys/updates",
        nullptr,
    };

    constexpr const char * TRANSLATION_PATHS[] =
    {
        "sys/user",
        "sys/factory-test",
        "assets",
        "sys/updates",
        nullptr
    };

    pthread_mutex_t g_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
    phmap::flat_hash_set<vfsn::linux::internal::FILEX*> g_fdlist;
    phmap::flat_hash_set<DIR*> g_dirlist;
}

namespace vfsn::linux::internal
{
    bool redirect_to_image()
    {
        if(!g_readed) {
            const auto env = std::getenv(ENV_NAME);
            g_redirect = env && !std::strcmp(env,"1");
            g_readed = true;
        }
        return g_redirect;
    }

    bool redirect_to_image(const char* inpath)
    {
        auto native_redirect = redirect_to_image();
        auto redirect = native_redirect;
        if(native_redirect) {
            for(auto path=ALLOWED_PATHS; *path; ++path) {
                if( std::strstr(inpath,*path)==inpath) {
                    redirect = false;
                    break;
                }
            }
        }
        if(native_redirect && !redirect)
        {
            for(auto path=EXCLUDED_PATHS; *path; ++path) {
                if( std::strstr(inpath,*path)==inpath) {
                    redirect = true;
                    break;
                }
            }
        }
        return redirect;
    }

    const char* npath_translate(const char* inpath, char *buffer)
    {
        for(size_t trans_pos=0; EXCLUDED_PATHS[trans_pos]; ++trans_pos) {
            if( std::strstr(inpath,EXCLUDED_PATHS[trans_pos])==inpath) {
                std::strncpy(buffer,TRANSLATION_PATHS[trans_pos],PATH_MAX);
                std::strncat(buffer,inpath+std::strlen(EXCLUDED_PATHS[trans_pos]), PATH_MAX);
                return buffer;
            }
        }
        return inpath;
    }

    bool is_image_handle(const FILE* fil)
    {
        return false;
    }

    int get_native_fd(FILEX* file)
    {
        return file ? (FIRST_FILEDESC + file->fd) : -1;
    }

    bool is_image_fd(int fd)
    {
        return fd >= FIRST_FILEDESC;
    }

    FILEX* allocate_filex(int fd)
    {
        auto ret = new FILEX;
        ret->fd = fd;
        pthread_mutex_lock(&g_lock);
        g_fdlist.emplace( ret );
        pthread_mutex_unlock(&g_lock);
        return ret;
    }

    void add_DIR_to_image_list(DIR* indir)
    {
        pthread_mutex_lock(&g_lock);
        g_dirlist.emplace( indir );
        pthread_mutex_unlock(&g_lock);
    }

    void remove_DIR_from_image_list(DIR* indir)
    {
        pthread_mutex_lock(&g_lock);
        auto fres = g_dirlist.find(indir);
        if(fres != g_dirlist.end())
        {
            g_dirlist.erase(fres);
        }
        pthread_mutex_unlock(&g_lock);
    }

    bool is_image_DIR(DIR* indir)
    {
        if(indir==nullptr) {
            return false;
        }
        pthread_mutex_lock(&g_lock);
        auto fres = g_dirlist.find(indir);
        auto isntdir = ( fres != g_dirlist.end() );
        pthread_mutex_unlock(&g_lock);
        return isntdir;
    }

    bool is_filex(const void* fd)
    {
        if(fd==nullptr) {
            return false;
        }
        pthread_mutex_lock(&g_lock);
        auto fres = g_fdlist.find(reinterpret_cast<const FILEX*>(fd));
        auto isfilex = ( fres != g_fdlist.end() );
        pthread_mutex_unlock(&g_lock);
        return isfilex;
    }

    void remove_filex(FILEX *fil)
    {
        pthread_mutex_lock(&g_lock);
        auto fres = g_fdlist.find(fil);
        if(fres != g_fdlist.end())
        {
            g_fdlist.erase(fres);
            delete fil;
        }
        pthread_mutex_unlock(&g_lock);
    }

    void debug_trace_syscall(const char* fn, const char* format, ...)
    {
        auto rvprint = reinterpret_cast<decltype(&vfprintf)>(dlsym(RTLD_NEXT, "vfprintf"));
        auto rprint = reinterpret_cast<decltype(&fprintf)>(dlsym(RTLD_NEXT, "fprintf"));
        rprint(stderr,">>>>>>> IOFUNC: [%s] ", fn);
        va_list args;
        va_start(args, format);
        rvprint(stderr, format, args);
        va_end(args);
        rprint(stderr," >>>>>>>>>>>\n");
    }
}