]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - module/zcommon/zfs_namecheck.c
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / module / zcommon / zfs_namecheck.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
27  */
28
29 /*
30  * Common name validation routines for ZFS.  These routines are shared by the
31  * userland code as well as the ioctl() layer to ensure that we don't
32  * inadvertently expose a hole through direct ioctl()s that never gets tested.
33  * In userland, however, we want significantly more information about _why_ the
34  * name is invalid.  In the kernel, we only care whether it's valid or not.
35  * Each routine therefore takes a 'namecheck_err_t' which describes exactly why
36  * the name failed to validate.
37  */
38
39 #if !defined(_KERNEL)
40 #include <string.h>
41 #endif
42
43 #include <sys/dsl_dir.h>
44 #include <sys/param.h>
45 #include <sys/nvpair.h>
46 #include "zfs_namecheck.h"
47 #include "zfs_deleg.h"
48
49 /*
50  * Deeply nested datasets can overflow the stack, so we put a limit
51  * in the amount of nesting a path can have. zfs_max_dataset_nesting
52  * can be tuned temporarily to fix existing datasets that exceed our
53  * predefined limit.
54  */
55 int zfs_max_dataset_nesting = 50;
56
57 static int
58 valid_char(char c)
59 {
60         return ((c >= 'a' && c <= 'z') ||
61             (c >= 'A' && c <= 'Z') ||
62             (c >= '0' && c <= '9') ||
63             c == '-' || c == '_' || c == '.' || c == ':' || c == ' ');
64 }
65
66 /*
67  * Looks at a path and returns its level of nesting (depth).
68  */
69 int
70 get_dataset_depth(const char *path)
71 {
72         const char *loc = path;
73         int nesting = 0;
74
75         /*
76          * Keep track of nesting until you hit the end of the
77          * path or found the snapshot/bookmark separator.
78          */
79         for (int i = 0; loc[i] != '\0' &&
80             loc[i] != '@' &&
81             loc[i] != '#'; i++) {
82                 if (loc[i] == '/')
83                         nesting++;
84         }
85
86         return (nesting);
87 }
88
89 /*
90  * Snapshot names must be made up of alphanumeric characters plus the following
91  * characters:
92  *
93  *      [-_.: ]
94  *
95  * Returns 0 on success, -1 on error.
96  */
97 int
98 zfs_component_namecheck(const char *path, namecheck_err_t *why, char *what)
99 {
100         const char *loc;
101
102         if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) {
103                 if (why)
104                         *why = NAME_ERR_TOOLONG;
105                 return (-1);
106         }
107
108         if (path[0] == '\0') {
109                 if (why)
110                         *why = NAME_ERR_EMPTY_COMPONENT;
111                 return (-1);
112         }
113
114         for (loc = path; *loc; loc++) {
115                 if (!valid_char(*loc)) {
116                         if (why) {
117                                 *why = NAME_ERR_INVALCHAR;
118                                 *what = *loc;
119                         }
120                         return (-1);
121                 }
122         }
123         return (0);
124 }
125
126
127 /*
128  * Permissions set name must start with the letter '@' followed by the
129  * same character restrictions as snapshot names, except that the name
130  * cannot exceed 64 characters.
131  *
132  * Returns 0 on success, -1 on error.
133  */
134 int
135 permset_namecheck(const char *path, namecheck_err_t *why, char *what)
136 {
137         if (strlen(path) >= ZFS_PERMSET_MAXLEN) {
138                 if (why)
139                         *why = NAME_ERR_TOOLONG;
140                 return (-1);
141         }
142
143         if (path[0] != '@') {
144                 if (why) {
145                         *why = NAME_ERR_NO_AT;
146                         *what = path[0];
147                 }
148                 return (-1);
149         }
150
151         return (zfs_component_namecheck(&path[1], why, what));
152 }
153
154 /*
155  * Dataset paths should not be deeper than zfs_max_dataset_nesting
156  * in terms of nesting.
157  *
158  * Returns 0 on success, -1 on error.
159  */
160 int
161 dataset_nestcheck(const char *path)
162 {
163         return ((get_dataset_depth(path) < zfs_max_dataset_nesting) ? 0 : -1);
164 }
165
166 /*
167  * Entity names must be of the following form:
168  *
169  *      [component/]*[component][(@|#)component]?
170  *
171  * Where each component is made up of alphanumeric characters plus the following
172  * characters:
173  *
174  *      [-_.: %]
175  *
176  * We allow '%' here as we use that character internally to create unique
177  * names for temporary clones (for online recv).
178  *
179  * Returns 0 on success, -1 on error.
180  */
181 int
182 entity_namecheck(const char *path, namecheck_err_t *why, char *what)
183 {
184         const char *end;
185
186         EQUIV(why == NULL, what == NULL);
187
188         /*
189          * Make sure the name is not too long.
190          */
191         if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) {
192                 if (why)
193                         *why = NAME_ERR_TOOLONG;
194                 return (-1);
195         }
196
197         /* Explicitly check for a leading slash.  */
198         if (path[0] == '/') {
199                 if (why)
200                         *why = NAME_ERR_LEADING_SLASH;
201                 return (-1);
202         }
203
204         if (path[0] == '\0') {
205                 if (why)
206                         *why = NAME_ERR_EMPTY_COMPONENT;
207                 return (-1);
208         }
209
210         const char *start = path;
211         boolean_t found_delim = B_FALSE;
212         for (;;) {
213                 /* Find the end of this component */
214                 end = start;
215                 while (*end != '/' && *end != '@' && *end != '#' &&
216                     *end != '\0')
217                         end++;
218
219                 if (*end == '\0' && end[-1] == '/') {
220                         /* trailing slashes are not allowed */
221                         if (why)
222                                 *why = NAME_ERR_TRAILING_SLASH;
223                         return (-1);
224                 }
225
226                 /* Validate the contents of this component */
227                 for (const char *loc = start; loc != end; loc++) {
228                         if (!valid_char(*loc) && *loc != '%') {
229                                 if (why) {
230                                         *why = NAME_ERR_INVALCHAR;
231                                         *what = *loc;
232                                 }
233                                 return (-1);
234                         }
235                 }
236
237                 if (*end == '\0' || *end == '/') {
238                         int component_length = end - start;
239                         /* Validate the contents of this component is not '.' */
240                         if (component_length == 1) {
241                                 if (start[0] == '.') {
242                                         if (why)
243                                                 *why = NAME_ERR_SELF_REF;
244                                         return (-1);
245                                 }
246                         }
247
248                         /* Validate the content of this component is not '..' */
249                         if (component_length == 2) {
250                                 if (start[0] == '.' && start[1] == '.') {
251                                         if (why)
252                                                 *why = NAME_ERR_PARENT_REF;
253                                         return (-1);
254                                 }
255                         }
256                 }
257
258                 /* Snapshot or bookmark delimiter found */
259                 if (*end == '@' || *end == '#') {
260                         /* Multiple delimiters are not allowed */
261                         if (found_delim != 0) {
262                                 if (why)
263                                         *why = NAME_ERR_MULTIPLE_DELIMITERS;
264                                 return (-1);
265                         }
266
267                         found_delim = B_TRUE;
268                 }
269
270                 /* Zero-length components are not allowed */
271                 if (start == end) {
272                         if (why)
273                                 *why = NAME_ERR_EMPTY_COMPONENT;
274                         return (-1);
275                 }
276
277                 /* If we've reached the end of the string, we're OK */
278                 if (*end == '\0')
279                         return (0);
280
281                 /*
282                  * If there is a '/' in a snapshot or bookmark name
283                  * then report an error
284                  */
285                 if (*end == '/' && found_delim != 0) {
286                         if (why)
287                                 *why = NAME_ERR_TRAILING_SLASH;
288                         return (-1);
289                 }
290
291                 /* Update to the next component */
292                 start = end + 1;
293         }
294 }
295
296 /*
297  * Dataset is any entity, except bookmark
298  */
299 int
300 dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
301 {
302         int ret = entity_namecheck(path, why, what);
303
304         if (ret == 0 && strchr(path, '#') != NULL) {
305                 if (why != NULL) {
306                         *why = NAME_ERR_INVALCHAR;
307                         *what = '#';
308                 }
309                 return (-1);
310         }
311
312         return (ret);
313 }
314
315 /*
316  * Assert path is a valid bookmark name
317  */
318 int
319 bookmark_namecheck(const char *path, namecheck_err_t *why, char *what)
320 {
321         int ret = entity_namecheck(path, why, what);
322
323         if (ret == 0 && strchr(path, '#') == NULL) {
324                 if (why != NULL) {
325                         *why = NAME_ERR_NO_POUND;
326                         *what = '#';
327                 }
328                 return (-1);
329         }
330
331         return (ret);
332 }
333
334 /*
335  * Assert path is a valid snapshot name
336  */
337 int
338 snapshot_namecheck(const char *path, namecheck_err_t *why, char *what)
339 {
340         int ret = entity_namecheck(path, why, what);
341
342         if (ret == 0 && strchr(path, '@') == NULL) {
343                 if (why != NULL) {
344                         *why = NAME_ERR_NO_AT;
345                         *what = '@';
346                 }
347                 return (-1);
348         }
349
350         return (ret);
351 }
352
353 /*
354  * mountpoint names must be of the following form:
355  *
356  *      /[component][/]*[component][/]
357  *
358  * Returns 0 on success, -1 on error.
359  */
360 int
361 mountpoint_namecheck(const char *path, namecheck_err_t *why)
362 {
363         const char *start, *end;
364
365         /*
366          * Make sure none of the mountpoint component names are too long.
367          * If a component name is too long then the mkdir of the mountpoint
368          * will fail but then the mountpoint property will be set to a value
369          * that can never be mounted.  Better to fail before setting the prop.
370          * Extra slashes are OK, they will be tossed by the mountpoint mkdir.
371          */
372
373         if (path == NULL || *path != '/') {
374                 if (why)
375                         *why = NAME_ERR_LEADING_SLASH;
376                 return (-1);
377         }
378
379         /* Skip leading slash  */
380         start = &path[1];
381         do {
382                 end = start;
383                 while (*end != '/' && *end != '\0')
384                         end++;
385
386                 if (end - start >= ZFS_MAX_DATASET_NAME_LEN) {
387                         if (why)
388                                 *why = NAME_ERR_TOOLONG;
389                         return (-1);
390                 }
391                 start = end + 1;
392
393         } while (*end != '\0');
394
395         return (0);
396 }
397
398 /*
399  * For pool names, we have the same set of valid characters as described in
400  * dataset names, with the additional restriction that the pool name must begin
401  * with a letter.  The pool names 'raidz' and 'mirror' are also reserved names
402  * that cannot be used.
403  *
404  * Returns 0 on success, -1 on error.
405  */
406 int
407 pool_namecheck(const char *pool, namecheck_err_t *why, char *what)
408 {
409         const char *c;
410
411         /*
412          * Make sure the name is not too long.
413          * If we're creating a pool with version >= SPA_VERSION_DSL_SCRUB (v11)
414          * we need to account for additional space needed by the origin ds which
415          * will also be snapshotted: "poolname"+"/"+"$ORIGIN"+"@"+"$ORIGIN".
416          * Play it safe and enforce this limit even if the pool version is < 11
417          * so it can be upgraded without issues.
418          */
419         if (strlen(pool) >= (ZFS_MAX_DATASET_NAME_LEN - 2 -
420             strlen(ORIGIN_DIR_NAME) * 2)) {
421                 if (why)
422                         *why = NAME_ERR_TOOLONG;
423                 return (-1);
424         }
425
426         c = pool;
427         while (*c != '\0') {
428                 if (!valid_char(*c)) {
429                         if (why) {
430                                 *why = NAME_ERR_INVALCHAR;
431                                 *what = *c;
432                         }
433                         return (-1);
434                 }
435                 c++;
436         }
437
438         if (!(*pool >= 'a' && *pool <= 'z') &&
439             !(*pool >= 'A' && *pool <= 'Z')) {
440                 if (why)
441                         *why = NAME_ERR_NOLETTER;
442                 return (-1);
443         }
444
445         if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) {
446                 if (why)
447                         *why = NAME_ERR_RESERVED;
448                 return (-1);
449         }
450
451         if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) {
452                 if (why)
453                         *why = NAME_ERR_DISKLIKE;
454                 return (-1);
455         }
456
457         return (0);
458 }
459
460 EXPORT_SYMBOL(entity_namecheck);
461 EXPORT_SYMBOL(pool_namecheck);
462 EXPORT_SYMBOL(dataset_namecheck);
463 EXPORT_SYMBOL(bookmark_namecheck);
464 EXPORT_SYMBOL(snapshot_namecheck);
465 EXPORT_SYMBOL(zfs_component_namecheck);
466 EXPORT_SYMBOL(dataset_nestcheck);
467 EXPORT_SYMBOL(get_dataset_depth);
468 EXPORT_SYMBOL(zfs_max_dataset_nesting);
469
470 ZFS_MODULE_PARAM(zfs, zfs_, max_dataset_nesting, INT, ZMOD_RW,
471         "Limit to the amount of nesting a path can have. Defaults to 50.");