~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/fs_parser.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/fs_parser.c (Version linux-6.12-rc7) and /fs/fs_parser.c (Version linux-5.3.18)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /* Filesystem parameter parser.                     2 /* Filesystem parameter parser.
  3  *                                                  3  *
  4  * Copyright (C) 2018 Red Hat, Inc. All Rights      4  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.c      5  * Written by David Howells (dhowells@redhat.com)
  6  */                                                 6  */
  7                                                     7 
  8 #include <linux/export.h>                           8 #include <linux/export.h>
  9 #include <linux/fs_context.h>                       9 #include <linux/fs_context.h>
 10 #include <linux/fs_parser.h>                       10 #include <linux/fs_parser.h>
 11 #include <linux/slab.h>                            11 #include <linux/slab.h>
 12 #include <linux/security.h>                        12 #include <linux/security.h>
 13 #include <linux/namei.h>                           13 #include <linux/namei.h>
 14 #include "internal.h"                              14 #include "internal.h"
 15                                                    15 
 16 static const struct constant_table bool_names[     16 static const struct constant_table bool_names[] = {
 17         { "",          false },                    17         { "",          false },
 18         { "1",          true },                    18         { "1",          true },
 19         { "false",      false },                   19         { "false",      false },
 20         { "no",         false },                   20         { "no",         false },
 21         { "true",       true },                    21         { "true",       true },
 22         { "yes",        true },                    22         { "yes",        true },
 23         { },                                   << 
 24 };                                                 23 };
 25                                                    24 
 26 static const struct constant_table *           << 
 27 __lookup_constant(const struct constant_table  << 
 28 {                                              << 
 29         for ( ; tbl->name; tbl++)              << 
 30                 if (strcmp(name, tbl->name) == << 
 31                         return tbl;            << 
 32         return NULL;                           << 
 33 }                                              << 
 34                                                << 
 35 /**                                                25 /**
 36  * lookup_constant - Look up a constant by nam     26  * lookup_constant - Look up a constant by name in an ordered table
 37  * @tbl: The table of constants to search.         27  * @tbl: The table of constants to search.
                                                   >>  28  * @tbl_size: The size of the table.
 38  * @name: The name to look up.                     29  * @name: The name to look up.
 39  * @not_found: The value to return if the name     30  * @not_found: The value to return if the name is not found.
 40  */                                                31  */
 41 int lookup_constant(const struct constant_tabl !!  32 int __lookup_constant(const struct constant_table *tbl, size_t tbl_size,
                                                   >>  33                       const char *name, int not_found)
 42 {                                                  34 {
 43         const struct constant_table *p = __loo !!  35         unsigned int i;
 44                                                    36 
 45         return p ? p->value : not_found;       !!  37         for (i = 0; i < tbl_size; i++)
 46 }                                              !!  38                 if (strcmp(name, tbl[i].name) == 0)
 47 EXPORT_SYMBOL(lookup_constant);                !!  39                         return tbl[i].value;
 48                                                    40 
 49 static inline bool is_flag(const struct fs_par !!  41         return not_found;
 50 {                                              << 
 51         return p->type == NULL;                << 
 52 }                                                  42 }
                                                   >>  43 EXPORT_SYMBOL(__lookup_constant);
 53                                                    44 
 54 static const struct fs_parameter_spec *fs_look     45 static const struct fs_parameter_spec *fs_lookup_key(
 55         const struct fs_parameter_spec *desc,  !!  46         const struct fs_parameter_description *desc,
 56         struct fs_parameter *param, bool *nega !!  47         const char *name)
 57 {                                                  48 {
 58         const struct fs_parameter_spec *p, *ot !!  49         const struct fs_parameter_spec *p;
 59         const char *name = param->key;         !!  50 
 60         bool want_flag = param->type == fs_val !!  51         if (!desc->specs)
 61                                                !!  52                 return NULL;
 62         *negated = false;                      !!  53 
 63         for (p = desc; p->name; p++) {         !!  54         for (p = desc->specs; p->name; p++)
 64                 if (strcmp(p->name, name) != 0 !!  55                 if (strcmp(p->name, name) == 0)
 65                         continue;              << 
 66                 if (likely(is_flag(p) == want_ << 
 67                         return p;                  56                         return p;
 68                 other = p;                     !!  57 
 69         }                                      !!  58         return NULL;
 70         if (want_flag) {                       << 
 71                 if (name[0] == 'n' && name[1]  << 
 72                         for (p = desc; p->name << 
 73                                 if (strcmp(p-> << 
 74                                         contin << 
 75                                 if (!(p->flags << 
 76                                         contin << 
 77                                 *negated = tru << 
 78                                 return p;      << 
 79                         }                      << 
 80                 }                              << 
 81         }                                      << 
 82         return other;                          << 
 83 }                                                  59 }
 84                                                    60 
 85 /*                                                 61 /*
 86  * __fs_parse - Parse a filesystem configurati !!  62  * fs_parse - Parse a filesystem configuration parameter
 87  * @log: The filesystem context to log errors  !!  63  * @fc: The filesystem context to log errors through.
 88  * @desc: The parameter description to use.        64  * @desc: The parameter description to use.
 89  * @param: The parameter.                          65  * @param: The parameter.
 90  * @result: Where to place the result of the p     66  * @result: Where to place the result of the parse
 91  *                                                 67  *
 92  * Parse a filesystem configuration parameter      68  * Parse a filesystem configuration parameter and attempt a conversion for a
 93  * simple parameter for which this is requeste     69  * simple parameter for which this is requested.  If successful, the determined
 94  * parameter ID is placed into @result->key, t     70  * parameter ID is placed into @result->key, the desired type is indicated in
 95  * @result->t and any converted value is place     71  * @result->t and any converted value is placed into an appropriate member of
 96  * the union in @result.                           72  * the union in @result.
 97  *                                                 73  *
 98  * The function returns the parameter number i     74  * The function returns the parameter number if the parameter was matched,
 99  * -ENOPARAM if it wasn't matched and @desc->i     75  * -ENOPARAM if it wasn't matched and @desc->ignore_unknown indicated that
100  * unknown parameters are okay and -EINVAL if      76  * unknown parameters are okay and -EINVAL if there was a conversion issue or
101  * the parameter wasn't recognised and unknown     77  * the parameter wasn't recognised and unknowns aren't okay.
102  */                                                78  */
103 int __fs_parse(struct p_log *log,              !!  79 int fs_parse(struct fs_context *fc,
104              const struct fs_parameter_spec *d !!  80              const struct fs_parameter_description *desc,
105              struct fs_parameter *param,           81              struct fs_parameter *param,
106              struct fs_parse_result *result)       82              struct fs_parse_result *result)
107 {                                                  83 {
108         const struct fs_parameter_spec *p;         84         const struct fs_parameter_spec *p;
                                                   >>  85         const struct fs_parameter_enum *e;
                                                   >>  86         int ret = -ENOPARAM, b;
109                                                    87 
                                                   >>  88         result->has_value = !!param->string;
                                                   >>  89         result->negated = false;
110         result->uint_64 = 0;                       90         result->uint_64 = 0;
111                                                    91 
112         p = fs_lookup_key(desc, param, &result !!  92         p = fs_lookup_key(desc, param->key);
113         if (!p)                                !!  93         if (!p) {
114                 return -ENOPARAM;              !!  94                 /* If we didn't find something that looks like "noxxx", see if
                                                   >>  95                  * "xxx" takes the "no"-form negative - but only if there
                                                   >>  96                  * wasn't an value.
                                                   >>  97                  */
                                                   >>  98                 if (result->has_value)
                                                   >>  99                         goto unknown_parameter;
                                                   >> 100                 if (param->key[0] != 'n' || param->key[1] != 'o' || !param->key[2])
                                                   >> 101                         goto unknown_parameter;
                                                   >> 102 
                                                   >> 103                 p = fs_lookup_key(desc, param->key + 2);
                                                   >> 104                 if (!p)
                                                   >> 105                         goto unknown_parameter;
                                                   >> 106                 if (!(p->flags & fs_param_neg_with_no))
                                                   >> 107                         goto unknown_parameter;
                                                   >> 108                 result->boolean = false;
                                                   >> 109                 result->negated = true;
                                                   >> 110         }
115                                                   111 
116         if (p->flags & fs_param_deprecated)       112         if (p->flags & fs_param_deprecated)
117                 warn_plog(log, "Deprecated par !! 113                 warnf(fc, "%s: Deprecated parameter '%s'",
                                                   >> 114                       desc->name, param->key);
                                                   >> 115 
                                                   >> 116         if (result->negated)
                                                   >> 117                 goto okay;
                                                   >> 118 
                                                   >> 119         /* Certain parameter types only take a string and convert it. */
                                                   >> 120         switch (p->type) {
                                                   >> 121         case __fs_param_wasnt_defined:
                                                   >> 122                 return -EINVAL;
                                                   >> 123         case fs_param_is_u32:
                                                   >> 124         case fs_param_is_u32_octal:
                                                   >> 125         case fs_param_is_u32_hex:
                                                   >> 126         case fs_param_is_s32:
                                                   >> 127         case fs_param_is_u64:
                                                   >> 128         case fs_param_is_enum:
                                                   >> 129         case fs_param_is_string:
                                                   >> 130                 if (param->type != fs_value_is_string)
                                                   >> 131                         goto bad_value;
                                                   >> 132                 if (!result->has_value) {
                                                   >> 133                         if (p->flags & fs_param_v_optional)
                                                   >> 134                                 goto okay;
                                                   >> 135                         goto bad_value;
                                                   >> 136                 }
                                                   >> 137                 /* Fall through */
                                                   >> 138         default:
                                                   >> 139                 break;
                                                   >> 140         }
118                                                   141 
119         /* Try to turn the type we were given     142         /* Try to turn the type we were given into the type desired by the
120          * parameter and give an error if we c    143          * parameter and give an error if we can't.
121          */                                       144          */
122         if (is_flag(p)) {                      !! 145         switch (p->type) {
123                 if (param->type != fs_value_is !! 146         case fs_param_is_flag:
124                         return inval_plog(log, !! 147                 if (param->type != fs_value_is_flag &&
125                                       param->k !! 148                     (param->type != fs_value_is_string || result->has_value))
126                 result->boolean = !result->neg !! 149                         return invalf(fc, "%s: Unexpected value for '%s'",
127         } else  {                              !! 150                                       desc->name, param->key);
128                 int ret = p->type(log, p, para !! 151                 result->boolean = true;
129                 if (ret)                       !! 152                 goto okay;
130                         return ret;            !! 153 
                                                   >> 154         case fs_param_is_bool:
                                                   >> 155                 switch (param->type) {
                                                   >> 156                 case fs_value_is_flag:
                                                   >> 157                         result->boolean = true;
                                                   >> 158                         goto okay;
                                                   >> 159                 case fs_value_is_string:
                                                   >> 160                         if (param->size == 0) {
                                                   >> 161                                 result->boolean = true;
                                                   >> 162                                 goto okay;
                                                   >> 163                         }
                                                   >> 164                         b = lookup_constant(bool_names, param->string, -1);
                                                   >> 165                         if (b == -1)
                                                   >> 166                                 goto bad_value;
                                                   >> 167                         result->boolean = b;
                                                   >> 168                         goto okay;
                                                   >> 169                 default:
                                                   >> 170                         goto bad_value;
                                                   >> 171                 }
                                                   >> 172 
                                                   >> 173         case fs_param_is_u32:
                                                   >> 174                 ret = kstrtouint(param->string, 0, &result->uint_32);
                                                   >> 175                 goto maybe_okay;
                                                   >> 176         case fs_param_is_u32_octal:
                                                   >> 177                 ret = kstrtouint(param->string, 8, &result->uint_32);
                                                   >> 178                 goto maybe_okay;
                                                   >> 179         case fs_param_is_u32_hex:
                                                   >> 180                 ret = kstrtouint(param->string, 16, &result->uint_32);
                                                   >> 181                 goto maybe_okay;
                                                   >> 182         case fs_param_is_s32:
                                                   >> 183                 ret = kstrtoint(param->string, 0, &result->int_32);
                                                   >> 184                 goto maybe_okay;
                                                   >> 185         case fs_param_is_u64:
                                                   >> 186                 ret = kstrtoull(param->string, 0, &result->uint_64);
                                                   >> 187                 goto maybe_okay;
                                                   >> 188 
                                                   >> 189         case fs_param_is_enum:
                                                   >> 190                 for (e = desc->enums; e->name[0]; e++) {
                                                   >> 191                         if (e->opt == p->opt &&
                                                   >> 192                             strcmp(e->name, param->string) == 0) {
                                                   >> 193                                 result->uint_32 = e->value;
                                                   >> 194                                 goto okay;
                                                   >> 195                         }
                                                   >> 196                 }
                                                   >> 197                 goto bad_value;
                                                   >> 198 
                                                   >> 199         case fs_param_is_string:
                                                   >> 200                 goto okay;
                                                   >> 201         case fs_param_is_blob:
                                                   >> 202                 if (param->type != fs_value_is_blob)
                                                   >> 203                         goto bad_value;
                                                   >> 204                 goto okay;
                                                   >> 205 
                                                   >> 206         case fs_param_is_fd: {
                                                   >> 207                 if (param->type != fs_value_is_file)
                                                   >> 208                         goto bad_value;
                                                   >> 209                 goto okay;
131         }                                         210         }
                                                   >> 211 
                                                   >> 212         case fs_param_is_blockdev:
                                                   >> 213         case fs_param_is_path:
                                                   >> 214                 goto okay;
                                                   >> 215         default:
                                                   >> 216                 BUG();
                                                   >> 217         }
                                                   >> 218 
                                                   >> 219 maybe_okay:
                                                   >> 220         if (ret < 0)
                                                   >> 221                 goto bad_value;
                                                   >> 222 okay:
132         return p->opt;                            223         return p->opt;
                                                   >> 224 
                                                   >> 225 bad_value:
                                                   >> 226         return invalf(fc, "%s: Bad value for '%s'", desc->name, param->key);
                                                   >> 227 unknown_parameter:
                                                   >> 228         return -ENOPARAM;
133 }                                                 229 }
134 EXPORT_SYMBOL(__fs_parse);                     !! 230 EXPORT_SYMBOL(fs_parse);
135                                                   231 
136 /**                                               232 /**
137  * fs_lookup_param - Look up a path referred t    233  * fs_lookup_param - Look up a path referred to by a parameter
138  * @fc: The filesystem context to log errors t    234  * @fc: The filesystem context to log errors through.
139  * @param: The parameter.                         235  * @param: The parameter.
140  * @want_bdev: T if want a blockdev               236  * @want_bdev: T if want a blockdev
141  * @flags: Pathwalk flags passed to filename_l << 
142  * @_path: The result of the lookup               237  * @_path: The result of the lookup
143  */                                               238  */
144 int fs_lookup_param(struct fs_context *fc,        239 int fs_lookup_param(struct fs_context *fc,
145                     struct fs_parameter *param    240                     struct fs_parameter *param,
146                     bool want_bdev,               241                     bool want_bdev,
147                     unsigned int flags,        << 
148                     struct path *_path)           242                     struct path *_path)
149 {                                                 243 {
150         struct filename *f;                       244         struct filename *f;
                                                   >> 245         unsigned int flags = 0;
151         bool put_f;                               246         bool put_f;
152         int ret;                                  247         int ret;
153                                                   248 
154         switch (param->type) {                    249         switch (param->type) {
155         case fs_value_is_string:                  250         case fs_value_is_string:
156                 f = getname_kernel(param->stri    251                 f = getname_kernel(param->string);
157                 if (IS_ERR(f))                    252                 if (IS_ERR(f))
158                         return PTR_ERR(f);        253                         return PTR_ERR(f);
159                 put_f = true;                     254                 put_f = true;
160                 break;                            255                 break;
                                                   >> 256         case fs_value_is_filename_empty:
                                                   >> 257                 flags = LOOKUP_EMPTY;
                                                   >> 258                 /* Fall through */
161         case fs_value_is_filename:                259         case fs_value_is_filename:
162                 f = param->name;                  260                 f = param->name;
163                 put_f = false;                    261                 put_f = false;
164                 break;                            262                 break;
165         default:                                  263         default:
166                 return invalf(fc, "%s: not usa    264                 return invalf(fc, "%s: not usable as path", param->key);
167         }                                         265         }
168                                                   266 
                                                   >> 267         f->refcnt++; /* filename_lookup() drops our ref. */
169         ret = filename_lookup(param->dirfd, f,    268         ret = filename_lookup(param->dirfd, f, flags, _path, NULL);
170         if (ret < 0) {                            269         if (ret < 0) {
171                 errorf(fc, "%s: Lookup failure    270                 errorf(fc, "%s: Lookup failure for '%s'", param->key, f->name);
172                 goto out;                         271                 goto out;
173         }                                         272         }
174                                                   273 
175         if (want_bdev &&                          274         if (want_bdev &&
176             !S_ISBLK(d_backing_inode(_path->de    275             !S_ISBLK(d_backing_inode(_path->dentry)->i_mode)) {
177                 path_put(_path);                  276                 path_put(_path);
178                 _path->dentry = NULL;             277                 _path->dentry = NULL;
179                 _path->mnt = NULL;                278                 _path->mnt = NULL;
180                 errorf(fc, "%s: Non-blockdev p    279                 errorf(fc, "%s: Non-blockdev passed as '%s'",
181                        param->key, f->name);      280                        param->key, f->name);
182                 ret = -ENOTBLK;                   281                 ret = -ENOTBLK;
183         }                                         282         }
184                                                   283 
185 out:                                              284 out:
186         if (put_f)                                285         if (put_f)
187                 putname(f);                       286                 putname(f);
188         return ret;                               287         return ret;
189 }                                                 288 }
190 EXPORT_SYMBOL(fs_lookup_param);                   289 EXPORT_SYMBOL(fs_lookup_param);
191                                                   290 
192 static int fs_param_bad_value(struct p_log *lo << 
193 {                                              << 
194         return inval_plog(log, "Bad value for  << 
195 }                                              << 
196                                                << 
197 int fs_param_is_bool(struct p_log *log, const  << 
198                      struct fs_parameter *para << 
199 {                                              << 
200         int b;                                 << 
201         if (param->type != fs_value_is_string) << 
202                 return fs_param_bad_value(log, << 
203         if (!*param->string && (p->flags & fs_ << 
204                 return 0;                      << 
205         b = lookup_constant(bool_names, param- << 
206         if (b == -1)                           << 
207                 return fs_param_bad_value(log, << 
208         result->boolean = b;                   << 
209         return 0;                              << 
210 }                                              << 
211 EXPORT_SYMBOL(fs_param_is_bool);               << 
212                                                << 
213 int fs_param_is_u32(struct p_log *log, const s << 
214                     struct fs_parameter *param << 
215 {                                              << 
216         int base = (unsigned long)p->data;     << 
217         if (param->type != fs_value_is_string) << 
218                 return fs_param_bad_value(log, << 
219         if (!*param->string && (p->flags & fs_ << 
220                 return 0;                      << 
221         if (kstrtouint(param->string, base, &r << 
222                 return fs_param_bad_value(log, << 
223         return 0;                              << 
224 }                                              << 
225 EXPORT_SYMBOL(fs_param_is_u32);                << 
226                                                << 
227 int fs_param_is_s32(struct p_log *log, const s << 
228                     struct fs_parameter *param << 
229 {                                              << 
230         if (param->type != fs_value_is_string) << 
231                 return fs_param_bad_value(log, << 
232         if (!*param->string && (p->flags & fs_ << 
233                 return 0;                      << 
234         if (kstrtoint(param->string, 0, &resul << 
235                 return fs_param_bad_value(log, << 
236         return 0;                              << 
237 }                                              << 
238 EXPORT_SYMBOL(fs_param_is_s32);                << 
239                                                << 
240 int fs_param_is_u64(struct p_log *log, const s << 
241                     struct fs_parameter *param << 
242 {                                              << 
243         if (param->type != fs_value_is_string) << 
244                 return fs_param_bad_value(log, << 
245         if (!*param->string && (p->flags & fs_ << 
246                 return 0;                      << 
247         if (kstrtoull(param->string, 0, &resul << 
248                 return fs_param_bad_value(log, << 
249         return 0;                              << 
250 }                                              << 
251 EXPORT_SYMBOL(fs_param_is_u64);                << 
252                                                << 
253 int fs_param_is_enum(struct p_log *log, const  << 
254                      struct fs_parameter *para << 
255 {                                              << 
256         const struct constant_table *c;        << 
257         if (param->type != fs_value_is_string) << 
258                 return fs_param_bad_value(log, << 
259         if (!*param->string && (p->flags & fs_ << 
260                 return 0;                      << 
261         c = __lookup_constant(p->data, param-> << 
262         if (!c)                                << 
263                 return fs_param_bad_value(log, << 
264         result->uint_32 = c->value;            << 
265         return 0;                              << 
266 }                                              << 
267 EXPORT_SYMBOL(fs_param_is_enum);               << 
268                                                << 
269 int fs_param_is_string(struct p_log *log, cons << 
270                        struct fs_parameter *pa << 
271 {                                              << 
272         if (param->type != fs_value_is_string  << 
273             (!*param->string && !(p->flags & f << 
274                 return fs_param_bad_value(log, << 
275         return 0;                              << 
276 }                                              << 
277 EXPORT_SYMBOL(fs_param_is_string);             << 
278                                                << 
279 int fs_param_is_blob(struct p_log *log, const  << 
280                      struct fs_parameter *para << 
281 {                                              << 
282         if (param->type != fs_value_is_blob)   << 
283                 return fs_param_bad_value(log, << 
284         return 0;                              << 
285 }                                              << 
286 EXPORT_SYMBOL(fs_param_is_blob);               << 
287                                                << 
288 int fs_param_is_fd(struct p_log *log, const st << 
289                   struct fs_parameter *param,  << 
290 {                                              << 
291         switch (param->type) {                 << 
292         case fs_value_is_string:               << 
293                 if ((!*param->string && !(p->f << 
294                     kstrtouint(param->string,  << 
295                         break;                 << 
296                 if (result->uint_32 <= INT_MAX << 
297                         return 0;              << 
298                 break;                         << 
299         case fs_value_is_file:                 << 
300                 result->uint_32 = param->dirfd << 
301                 if (result->uint_32 <= INT_MAX << 
302                         return 0;              << 
303                 break;                         << 
304         default:                               << 
305                 break;                         << 
306         }                                      << 
307         return fs_param_bad_value(log, param); << 
308 }                                              << 
309 EXPORT_SYMBOL(fs_param_is_fd);                 << 
310                                                << 
311 int fs_param_is_uid(struct p_log *log, const s << 
312                     struct fs_parameter *param << 
313 {                                              << 
314         kuid_t uid;                            << 
315                                                << 
316         if (fs_param_is_u32(log, p, param, res << 
317                 return fs_param_bad_value(log, << 
318                                                << 
319         uid = make_kuid(current_user_ns(), res << 
320         if (!uid_valid(uid))                   << 
321                 return inval_plog(log, "Invali << 
322                                                << 
323         result->uid = uid;                     << 
324         return 0;                              << 
325 }                                              << 
326 EXPORT_SYMBOL(fs_param_is_uid);                << 
327                                                << 
328 int fs_param_is_gid(struct p_log *log, const s << 
329                     struct fs_parameter *param << 
330 {                                              << 
331         kgid_t gid;                            << 
332                                                << 
333         if (fs_param_is_u32(log, p, param, res << 
334                 return fs_param_bad_value(log, << 
335                                                << 
336         gid = make_kgid(current_user_ns(), res << 
337         if (!gid_valid(gid))                   << 
338                 return inval_plog(log, "Invali << 
339                                                << 
340         result->gid = gid;                     << 
341         return 0;                              << 
342 }                                              << 
343 EXPORT_SYMBOL(fs_param_is_gid);                << 
344                                                << 
345 int fs_param_is_blockdev(struct p_log *log, co << 
346                   struct fs_parameter *param,  << 
347 {                                              << 
348         return 0;                              << 
349 }                                              << 
350 EXPORT_SYMBOL(fs_param_is_blockdev);           << 
351                                                << 
352 int fs_param_is_path(struct p_log *log, const  << 
353                      struct fs_parameter *para << 
354 {                                              << 
355         return 0;                              << 
356 }                                              << 
357 EXPORT_SYMBOL(fs_param_is_path);               << 
358                                                << 
359 #ifdef CONFIG_VALIDATE_FS_PARSER                  291 #ifdef CONFIG_VALIDATE_FS_PARSER
360 /**                                               292 /**
361  * validate_constant_table - Validate a consta    293  * validate_constant_table - Validate a constant table
                                                   >> 294  * @name: Name to use in reporting
362  * @tbl: The constant table to validate.          295  * @tbl: The constant table to validate.
363  * @tbl_size: The size of the table.              296  * @tbl_size: The size of the table.
364  * @low: The lowest permissible value.            297  * @low: The lowest permissible value.
365  * @high: The highest permissible value.          298  * @high: The highest permissible value.
366  * @special: One special permissible value out    299  * @special: One special permissible value outside of the range.
367  */                                               300  */
368 bool validate_constant_table(const struct cons    301 bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
369                              int low, int high    302                              int low, int high, int special)
370 {                                                 303 {
371         size_t i;                                 304         size_t i;
372         bool good = true;                         305         bool good = true;
373                                                   306 
374         if (tbl_size == 0) {                      307         if (tbl_size == 0) {
375                 pr_warn("VALIDATE C-TBL: Empty    308                 pr_warn("VALIDATE C-TBL: Empty\n");
376                 return true;                      309                 return true;
377         }                                         310         }
378                                                   311 
379         for (i = 0; i < tbl_size; i++) {          312         for (i = 0; i < tbl_size; i++) {
380                 if (!tbl[i].name) {               313                 if (!tbl[i].name) {
381                         pr_err("VALIDATE C-TBL    314                         pr_err("VALIDATE C-TBL[%zu]: Null\n", i);
382                         good = false;             315                         good = false;
383                 } else if (i > 0 && tbl[i - 1]    316                 } else if (i > 0 && tbl[i - 1].name) {
384                         int c = strcmp(tbl[i-1    317                         int c = strcmp(tbl[i-1].name, tbl[i].name);
385                                                   318 
386                         if (c == 0) {             319                         if (c == 0) {
387                                 pr_err("VALIDA    320                                 pr_err("VALIDATE C-TBL[%zu]: Duplicate %s\n",
388                                        i, tbl[    321                                        i, tbl[i].name);
389                                 good = false;     322                                 good = false;
390                         }                         323                         }
391                         if (c > 0) {              324                         if (c > 0) {
392                                 pr_err("VALIDA    325                                 pr_err("VALIDATE C-TBL[%zu]: Missorted %s>=%s\n",
393                                        i, tbl[    326                                        i, tbl[i-1].name, tbl[i].name);
394                                 good = false;     327                                 good = false;
395                         }                         328                         }
396                 }                                 329                 }
397                                                   330 
398                 if (tbl[i].value != special &&    331                 if (tbl[i].value != special &&
399                     (tbl[i].value < low || tbl    332                     (tbl[i].value < low || tbl[i].value > high)) {
400                         pr_err("VALIDATE C-TBL    333                         pr_err("VALIDATE C-TBL[%zu]: %s->%d const out of range (%d-%d)\n",
401                                i, tbl[i].name,    334                                i, tbl[i].name, tbl[i].value, low, high);
402                         good = false;             335                         good = false;
403                 }                                 336                 }
404         }                                         337         }
405                                                   338 
406         return good;                              339         return good;
407 }                                                 340 }
408                                                   341 
409 /**                                               342 /**
410  * fs_validate_description - Validate a parame    343  * fs_validate_description - Validate a parameter description
411  * @name: The parameter name to search for.    << 
412  * @desc: The parameter description to validat    344  * @desc: The parameter description to validate.
413  */                                               345  */
414 bool fs_validate_description(const char *name, !! 346 bool fs_validate_description(const struct fs_parameter_description *desc)
415         const struct fs_parameter_spec *desc)  << 
416 {                                                 347 {
417         const struct fs_parameter_spec *param,    348         const struct fs_parameter_spec *param, *p2;
418         bool good = true;                      !! 349         const struct fs_parameter_enum *e;
                                                   >> 350         const char *name = desc->name;
                                                   >> 351         unsigned int nr_params = 0;
                                                   >> 352         bool good = true, enums = false;
                                                   >> 353 
                                                   >> 354         pr_notice("*** VALIDATE %s ***\n", name);
                                                   >> 355 
                                                   >> 356         if (!name[0]) {
                                                   >> 357                 pr_err("VALIDATE Parser: No name\n");
                                                   >> 358                 name = "Unknown";
                                                   >> 359                 good = false;
                                                   >> 360         }
                                                   >> 361 
                                                   >> 362         if (desc->specs) {
                                                   >> 363                 for (param = desc->specs; param->name; param++) {
                                                   >> 364                         enum fs_parameter_type t = param->type;
                                                   >> 365 
                                                   >> 366                         /* Check that the type is in range */
                                                   >> 367                         if (t == __fs_param_wasnt_defined ||
                                                   >> 368                             t >= nr__fs_parameter_type) {
                                                   >> 369                                 pr_err("VALIDATE %s: PARAM[%s] Bad type %u\n",
                                                   >> 370                                        name, param->name, t);
                                                   >> 371                                 good = false;
                                                   >> 372                         } else if (t == fs_param_is_enum) {
                                                   >> 373                                 enums = true;
                                                   >> 374                         }
                                                   >> 375 
                                                   >> 376                         /* Check for duplicate parameter names */
                                                   >> 377                         for (p2 = desc->specs; p2 < param; p2++) {
                                                   >> 378                                 if (strcmp(param->name, p2->name) == 0) {
                                                   >> 379                                         pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n",
                                                   >> 380                                                name, param->name);
                                                   >> 381                                         good = false;
                                                   >> 382                                 }
                                                   >> 383                         }
                                                   >> 384                 }
419                                                   385 
420         for (param = desc; param->name; param+ !! 386                 nr_params = param - desc->specs;
421                 /* Check for duplicate paramet !! 387         }
422                 for (p2 = desc; p2 < param; p2 !! 388 
423                         if (strcmp(param->name !! 389         if (desc->enums) {
424                                 if (is_flag(pa !! 390                 if (!nr_params) {
425                                         contin !! 391                         pr_err("VALIDATE %s: Enum table but no parameters\n",
426                                 pr_err("VALIDA !! 392                                name);
                                                   >> 393                         good = false;
                                                   >> 394                         goto no_enums;
                                                   >> 395                 }
                                                   >> 396                 if (!enums) {
                                                   >> 397                         pr_err("VALIDATE %s: Enum table but no enum-type values\n",
                                                   >> 398                                name);
                                                   >> 399                         good = false;
                                                   >> 400                         goto no_enums;
                                                   >> 401                 }
                                                   >> 402 
                                                   >> 403                 for (e = desc->enums; e->name[0]; e++) {
                                                   >> 404                         /* Check that all entries in the enum table have at
                                                   >> 405                          * least one parameter that uses them.
                                                   >> 406                          */
                                                   >> 407                         for (param = desc->specs; param->name; param++) {
                                                   >> 408                                 if (param->opt == e->opt &&
                                                   >> 409                                     param->type != fs_param_is_enum) {
                                                   >> 410                                         pr_err("VALIDATE %s: e[%tu] enum val for %s\n",
                                                   >> 411                                                name, e - desc->enums, param->name);
                                                   >> 412                                         good = false;
                                                   >> 413                                 }
                                                   >> 414                         }
                                                   >> 415                 }
                                                   >> 416 
                                                   >> 417                 /* Check that all enum-type parameters have at least one enum
                                                   >> 418                  * value in the enum table.
                                                   >> 419                  */
                                                   >> 420                 for (param = desc->specs; param->name; param++) {
                                                   >> 421                         if (param->type != fs_param_is_enum)
                                                   >> 422                                 continue;
                                                   >> 423                         for (e = desc->enums; e->name[0]; e++)
                                                   >> 424                                 if (e->opt == param->opt)
                                                   >> 425                                         break;
                                                   >> 426                         if (!e->name[0]) {
                                                   >> 427                                 pr_err("VALIDATE %s: PARAM[%s] enum with no values\n",
427                                        name, p    428                                        name, param->name);
428                                 good = false;     429                                 good = false;
429                         }                         430                         }
430                 }                                 431                 }
                                                   >> 432         } else {
                                                   >> 433                 if (enums) {
                                                   >> 434                         pr_err("VALIDATE %s: enum-type values, but no enum table\n",
                                                   >> 435                                name);
                                                   >> 436                         good = false;
                                                   >> 437                         goto no_enums;
                                                   >> 438                 }
431         }                                         439         }
                                                   >> 440 
                                                   >> 441 no_enums:
432         return good;                              442         return good;
433 }                                                 443 }
434 #endif /* CONFIG_VALIDATE_FS_PARSER */            444 #endif /* CONFIG_VALIDATE_FS_PARSER */
435                                                   445 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php