• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/statfs.h>
32 #include <sys/mount.h>
33 #include "proc_fs.h"
34 #include "internal.h"
35 #include "los_process_pri.h"
36 #include "user_copy.h"
37 #include "los_memory.h"
38 
39 #ifdef LOSCFG_KERNEL_CONTAINER
40 struct ProcSysUser {
41     char         *name;
42     mode_t       mode;
43     int          type;
44     const struct ProcFileOperations *fileOps;
45 };
46 
MemUserCopy(const char * src,size_t len,char ** kbuf)47 static unsigned int MemUserCopy(const char *src, size_t len, char **kbuf)
48 {
49     if (LOS_IsUserAddressRange((VADDR_T)(UINTPTR)src, len)) {
50         char *kernelBuf = LOS_MemAlloc(m_aucSysMem1, len + 1);
51         if (kernelBuf == NULL) {
52             return ENOMEM;
53         }
54 
55         if (LOS_ArchCopyFromUser(kernelBuf, src, len) != 0) {
56             (VOID)LOS_MemFree(m_aucSysMem1, kernelBuf);
57             return EFAULT;
58         }
59         kernelBuf[len] = '\0';
60         *kbuf = kernelBuf;
61         return 0;
62     }
63     return 0;
64 }
65 
GetContainerLimitValue(struct ProcFile * pf,const CHAR * buf,size_t count)66 static int GetContainerLimitValue(struct ProcFile *pf, const CHAR *buf, size_t count)
67 {
68     int value;
69     char *kbuf = NULL;
70 
71     if ((pf == NULL) || (pf->pPDE == NULL) || (buf == NULL) || (count <= 0)) {
72         return -EINVAL;
73     }
74 
75     unsigned ret = MemUserCopy(buf, count, &kbuf);
76     if (ret != 0) {
77         return -ret;
78     } else if ((ret == 0) && (kbuf != NULL)) {
79         buf = (const char *)kbuf;
80     }
81 
82     if (strspn(buf, "0123456789") != count) {
83         (void)LOS_MemFree(m_aucSysMem1, kbuf);
84         return -EINVAL;
85     }
86     value = atoi(buf);
87     (void)LOS_MemFree(m_aucSysMem1, kbuf);
88     return value;
89 }
90 
ProcSysUserWrite(struct ProcFile * pf,const char * buf,size_t size,loff_t * ppos)91 static ssize_t ProcSysUserWrite(struct ProcFile *pf, const char *buf, size_t size, loff_t *ppos)
92 {
93     (void)ppos;
94     unsigned ret;
95     int value = GetContainerLimitValue(pf, buf, size);
96     if (value < 0) {
97         return -EINVAL;
98     }
99 
100     ContainerType type = (ContainerType)(uintptr_t)pf->pPDE->data;
101     ret = OsSetContainerLimit(type, value);
102     if (ret != LOS_OK) {
103         return -EINVAL;
104     }
105     return size;
106 }
107 
ProcSysUserRead(struct SeqBuf * seqBuf,void * v)108 static int ProcSysUserRead(struct SeqBuf *seqBuf, void *v)
109 {
110     unsigned ret;
111     if ((seqBuf == NULL) || (v == NULL)) {
112         return EINVAL;
113     }
114 
115     ContainerType type = (ContainerType)(uintptr_t)v;
116     ret = OsGetContainerLimit(type);
117     if (ret == OS_INVALID_VALUE) {
118         return EINVAL;
119     }
120     (void)LosBufPrintf(seqBuf, "\nlimit: %u\n", ret);
121     (void)LosBufPrintf(seqBuf, "count: %u\n", OsGetContainerCount(type));
122     return 0;
123 }
124 
125 static const struct ProcFileOperations SYS_USER_OPT = {
126     .read = ProcSysUserRead,
127     .write = ProcSysUserWrite,
128 };
129 
130 static struct ProcSysUser g_sysUser[] = {
131 #ifdef LOSCFG_MNT_CONTAINER
132     {
133         .name = "max_mnt_container",
134         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
135         .type = MNT_CONTAINER,
136         .fileOps = &SYS_USER_OPT
137 
138     },
139 #endif
140 #ifdef LOSCFG_PID_CONTAINER
141     {
142         .name = "max_pid_container",
143         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
144         .type = PID_CONTAINER,
145         .fileOps = &SYS_USER_OPT
146     },
147 #endif
148 #ifdef LOSCFG_USER_CONTAINER
149     {
150         .name = "max_user_container",
151         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
152         .type = USER_CONTAINER,
153         .fileOps = &SYS_USER_OPT
154 
155     },
156 #endif
157 #ifdef LOSCFG_UTS_CONTAINER
158     {
159         .name = "max_uts_container",
160         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
161         .type = UTS_CONTAINER,
162         .fileOps = &SYS_USER_OPT
163 
164     },
165 #endif
166 #ifdef LOSCFG_UTS_CONTAINER
167     {
168         .name = "max_time_container",
169         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
170         .type = UTS_CONTAINER,
171         .fileOps = &SYS_USER_OPT
172 
173     },
174 #endif
175 #ifdef LOSCFG_IPC_CONTAINER
176     {
177         .name = "max_ipc_container",
178         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
179         .type = IPC_CONTAINER,
180         .fileOps = &SYS_USER_OPT
181     },
182 #endif
183 #ifdef LOSCFG_NET_CONTAINER
184     {
185         .name = "max_net_container",
186         .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH,
187         .type = NET_CONTAINER,
188         .fileOps = &SYS_USER_OPT
189     },
190 #endif
191 };
192 
ProcCreateSysUser(struct ProcDirEntry * parent)193 static int ProcCreateSysUser(struct ProcDirEntry *parent)
194 {
195     struct ProcDataParm parm;
196     for (int index = 0; index < (sizeof(g_sysUser) / sizeof(struct ProcSysUser)); index++) {
197         struct ProcSysUser *sysUser = &g_sysUser[index];
198         parm.data = (void *)(uintptr_t)sysUser->type;
199         parm.dataType = PROC_DATA_STATIC;
200         struct ProcDirEntry *userFile = ProcCreateData(sysUser->name, sysUser->mode, parent, sysUser->fileOps, &parm);
201         if (userFile == NULL) {
202             PRINT_ERR("create /proc/%s/%s error!\n", parent->name, sysUser->name);
203             return -1;
204         }
205     }
206     return 0;
207 }
208 
209 #define PROC_SYS_USER_MODE (S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
ProcSysUserInit(void)210 void ProcSysUserInit(void)
211 {
212     struct ProcDirEntry *parentPDE = CreateProcEntry("sys", PROC_SYS_USER_MODE, NULL);
213     if (parentPDE == NULL) {
214         return;
215     }
216     struct ProcDirEntry *pde = CreateProcEntry("user", PROC_SYS_USER_MODE, parentPDE);
217     if (pde == NULL) {
218         PRINT_ERR("create /proc/process error!\n");
219         return;
220     }
221 
222     int ret = ProcCreateSysUser(pde);
223     if (ret < 0) {
224         PRINT_ERR("Create proc sys user failed!\n");
225     }
226     return;
227 }
228 #endif
229