• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "mount.h"
16 
17 #include <sys/mount.h>
18 #include <securec.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 
FindMountDeviceByPath(const char * toQuery,char * dev)24 bool FindMountDeviceByPath(const char *toQuery, char *dev)
25 {
26     int fd;
27     int res;
28     char *token = nullptr;
29     const char delims[] = "\n";
30     char buf[BUF_SIZE_DEFAULT2];
31 
32     fd = open("/proc/mounts", O_RDONLY | O_CLOEXEC);
33     if (fd < 0) {
34         return false;
35     }
36     read(fd, buf, sizeof(buf) - 1);
37     close(fd);
38     buf[sizeof(buf) - 1] = '\0';
39     token = strtok(buf, delims);
40 
41     while (token) {
42         char dir[BUF_SIZE_SMALL] = "";
43         int freq;
44         int passnno;
45         // clang-format off
46         res = sscanf_s(token, "%255s %255s %*s %*s %d %d\n", dev, strlen(dev),
47                        dir, sizeof(dir), &freq, &passnno);
48         // clang-format on
49         dev[BUF_SIZE_SMALL - 1] = '\0';
50         dir[BUF_SIZE_SMALL - 1] = '\0';
51         if (res == 4 && (strcmp(toQuery, dir) == 0)) {  // 4 : The correct number of parameters
52             return true;
53         }
54         token = strtok(nullptr, delims);
55     }
56     return false;
57 }
58 
RemountPartition(const char * dir)59 bool RemountPartition(const char *dir)
60 {
61     int fd;
62     int off = 0;
63     char dev[BUF_SIZE_SMALL] = "";
64 
65     if (!FindMountDeviceByPath(dir, dev) || strlen(dev) < 4) {  // 4 : file count
66         return false;
67     }
68 
69     if ((fd = open(dev, O_RDONLY | O_CLOEXEC)) < 0) {
70         return false;
71     }
72     ioctl(fd, BLKROSET, &off);
73     close(fd);
74 
75     if (mount(dev, dir, "none", MS_REMOUNT, nullptr) < 0) {
76         return false;
77     }
78     return true;
79 }
80 
RemountDevice()81 bool RemountDevice()
82 {
83     if (getuid() != 0) {
84         return false;
85     }
86     struct stat info;
87     if (!lstat("/vendor", &info) && (info.st_mode & S_IFMT) == S_IFDIR) {
88         // has vendor
89         if (!RemountPartition("/vendor")) {
90             return false;
91         }
92     }
93     if (!lstat("/data", &info) && (info.st_mode & S_IFMT) == S_IFDIR) {
94         if (!RemountPartition("/data")) {
95             return false;
96         }
97     }
98     return true;
99 }