]> granicus.if.org Git - zfs/blob - module/zcommon/zfs_namecheck.c
Reference zfeature.c in a SPA_VERSION comment
[zfs] / 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 seperator.
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         /*
187          * Make sure the name is not too long.
188          */
189         if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) {
190                 if (why)
191                         *why = NAME_ERR_TOOLONG;
192                 return (-1);
193         }
194
195         /* Explicitly check for a leading slash.  */
196         if (path[0] == '/') {
197                 if (why)
198                         *why = NAME_ERR_LEADING_SLASH;
199                 return (-1);
200         }
201
202         if (path[0] == '\0') {
203                 if (why)
204                         *why = NAME_ERR_EMPTY_COMPONENT;
205                 return (-1);
206         }
207
208         const char *start = path;
209         boolean_t found_delim = B_FALSE;
210         for (;;) {
211                 /* Find the end of this component */
212                 end = start;
213                 while (*end != '/' && *end != '@' && *end != '#' &&
214                     *end != '\0')
215                         end++;
216
217                 if (*end == '\0' && end[-1] == '/') {
218                         /* trailing slashes are not allowed */
219                         if (why)
220                                 *why = NAME_ERR_TRAILING_SLASH;
221                         return (-1);
222                 }
223
224                 /* Validate the contents of this component */
225                 for (const char *loc = start; loc != end; loc++) {
226                         if (!valid_char(*loc) && *loc != '%') {
227                                 if (why) {
228                                         *why = NAME_ERR_INVALCHAR;
229                                         *what = *loc;
230                                 }
231                                 return (-1);
232                         }
233                 }
234
235                 /* Snapshot or bookmark delimiter found */
236                 if (*end == '@' || *end == '#') {
237                         /* Multiple delimiters are not allowed */
238                         if (found_delim != 0) {
239                                 if (why)
240                                         *why = NAME_ERR_MULTIPLE_DELIMITERS;
241                                 return (-1);
242                         }
243
244                         found_delim = B_TRUE;
245                 }
246
247                 /* Zero-length components are not allowed */
248                 if (start == end) {
249                         if (why)
250                                 *why = NAME_ERR_EMPTY_COMPONENT;
251                         return (-1);
252                 }
253
254                 /* If we've reached the end of the string, we're OK */
255                 if (*end == '\0')
256                         return (0);
257
258                 /*
259                  * If there is a '/' in a snapshot or bookmark name
260                  * then report an error
261                  */
262                 if (*end == '/' && found_delim != 0) {
263                         if (why)
264                                 *why = NAME_ERR_TRAILING_SLASH;
265                         return (-1);
266                 }
267
268                 /* Update to the next component */
269                 start = end + 1;
270         }
271 }
272
273 /*
274  * Dataset is any entity, except bookmark
275  */
276 int
277 dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
278 {
279         int ret = entity_namecheck(path, why, what);
280
281         if (ret == 0 && strchr(path, '#') != NULL) {
282                 if (why != NULL) {
283                         *why = NAME_ERR_INVALCHAR;
284                         *what = '#';
285                 }
286                 return (-1);
287         }
288
289         return (ret);
290 }
291
292 /*
293  * mountpoint names must be of the following form:
294  *
295  *      /[component][/]*[component][/]
296  *
297  * Returns 0 on success, -1 on error.
298  */
299 int
300 mountpoint_namecheck(const char *path, namecheck_err_t *why)
301 {
302         const char *start, *end;
303
304         /*
305          * Make sure none of the mountpoint component names are too long.
306          * If a component name is too long then the mkdir of the mountpoint
307          * will fail but then the mountpoint property will be set to a value
308          * that can never be mounted.  Better to fail before setting the prop.
309          * Extra slashes are OK, they will be tossed by the mountpoint mkdir.
310          */
311
312         if (path == NULL || *path != '/') {
313                 if (why)
314                         *why = NAME_ERR_LEADING_SLASH;
315                 return (-1);
316         }
317
318         /* Skip leading slash  */
319         start = &path[1];
320         do {
321                 end = start;
322                 while (*end != '/' && *end != '\0')
323                         end++;
324
325                 if (end - start >= ZFS_MAX_DATASET_NAME_LEN) {
326                         if (why)
327                                 *why = NAME_ERR_TOOLONG;
328                         return (-1);
329                 }
330                 start = end + 1;
331
332         } while (*end != '\0');
333
334         return (0);
335 }
336
337 /*
338  * For pool names, we have the same set of valid characters as described in
339  * dataset names, with the additional restriction that the pool name must begin
340  * with a letter.  The pool names 'raidz' and 'mirror' are also reserved names
341  * that cannot be used.
342  *
343  * Returns 0 on success, -1 on error.
344  */
345 int
346 pool_namecheck(const char *pool, namecheck_err_t *why, char *what)
347 {
348         const char *c;
349
350         /*
351          * Make sure the name is not too long.
352          * If we're creating a pool with version >= SPA_VERSION_DSL_SCRUB (v11)
353          * we need to account for additional space needed by the origin ds which
354          * will also be snapshotted: "poolname"+"/"+"$ORIGIN"+"@"+"$ORIGIN".
355          * Play it safe and enforce this limit even if the pool version is < 11
356          * so it can be upgraded without issues.
357          */
358         if (strlen(pool) >= (ZFS_MAX_DATASET_NAME_LEN - 2 -
359             strlen(ORIGIN_DIR_NAME) * 2)) {
360                 if (why)
361                         *why = NAME_ERR_TOOLONG;
362                 return (-1);
363         }
364
365         c = pool;
366         while (*c != '\0') {
367                 if (!valid_char(*c)) {
368                         if (why) {
369                                 *why = NAME_ERR_INVALCHAR;
370                                 *what = *c;
371                         }
372                         return (-1);
373                 }
374                 c++;
375         }
376
377         if (!(*pool >= 'a' && *pool <= 'z') &&
378             !(*pool >= 'A' && *pool <= 'Z')) {
379                 if (why)
380                         *why = NAME_ERR_NOLETTER;
381                 return (-1);
382         }
383
384         if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) {
385                 if (why)
386                         *why = NAME_ERR_RESERVED;
387                 return (-1);
388         }
389
390         if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) {
391                 if (why)
392                         *why = NAME_ERR_DISKLIKE;
393                 return (-1);
394         }
395
396         return (0);
397 }
398
399 #if defined(_KERNEL)
400 EXPORT_SYMBOL(pool_namecheck);
401 EXPORT_SYMBOL(dataset_namecheck);
402 EXPORT_SYMBOL(zfs_component_namecheck);
403 EXPORT_SYMBOL(dataset_nestcheck);
404 EXPORT_SYMBOL(get_dataset_depth);
405 EXPORT_SYMBOL(zfs_max_dataset_nesting);
406
407 module_param(zfs_max_dataset_nesting, int, 0644);
408 MODULE_PARM_DESC(zfs_max_dataset_nesting, "Maximum depth of nested datasets");
409 #endif