0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/ctype.h>
0016 #include <linux/errno.h>
0017 #include <linux/export.h>
0018 #include <linux/kstrtox.h>
0019 #include <linux/math64.h>
0020 #include <linux/types.h>
0021 #include <linux/uaccess.h>
0022
0023 #include "kstrtox.h"
0024
0025 noinline
0026 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
0027 {
0028 if (*base == 0) {
0029 if (s[0] == '0') {
0030 if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
0031 *base = 16;
0032 else
0033 *base = 8;
0034 } else
0035 *base = 10;
0036 }
0037 if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
0038 s += 2;
0039 return s;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 noinline
0052 unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
0053 size_t max_chars)
0054 {
0055 unsigned long long res;
0056 unsigned int rv;
0057
0058 res = 0;
0059 rv = 0;
0060 while (max_chars--) {
0061 unsigned int c = *s;
0062 unsigned int lc = c | 0x20;
0063 unsigned int val;
0064
0065 if ('0' <= c && c <= '9')
0066 val = c - '0';
0067 else if ('a' <= lc && lc <= 'f')
0068 val = lc - 'a' + 10;
0069 else
0070 break;
0071
0072 if (val >= base)
0073 break;
0074
0075
0076
0077
0078 if (unlikely(res & (~0ull << 60))) {
0079 if (res > div_u64(ULLONG_MAX - val, base))
0080 rv |= KSTRTOX_OVERFLOW;
0081 }
0082 res = res * base + val;
0083 rv++;
0084 s++;
0085 }
0086 *p = res;
0087 return rv;
0088 }
0089
0090 noinline
0091 unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
0092 {
0093 return _parse_integer_limit(s, base, p, INT_MAX);
0094 }
0095
0096 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0097 {
0098 unsigned long long _res;
0099 unsigned int rv;
0100
0101 s = _parse_integer_fixup_radix(s, &base);
0102 rv = _parse_integer(s, base, &_res);
0103 if (rv & KSTRTOX_OVERFLOW)
0104 return -ERANGE;
0105 if (rv == 0)
0106 return -EINVAL;
0107 s += rv;
0108 if (*s == '\n')
0109 s++;
0110 if (*s)
0111 return -EINVAL;
0112 *res = _res;
0113 return 0;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 noinline
0132 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
0133 {
0134 if (s[0] == '+')
0135 s++;
0136 return _kstrtoull(s, base, res);
0137 }
0138 EXPORT_SYMBOL(kstrtoull);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 noinline
0156 int kstrtoll(const char *s, unsigned int base, long long *res)
0157 {
0158 unsigned long long tmp;
0159 int rv;
0160
0161 if (s[0] == '-') {
0162 rv = _kstrtoull(s + 1, base, &tmp);
0163 if (rv < 0)
0164 return rv;
0165 if ((long long)-tmp > 0)
0166 return -ERANGE;
0167 *res = -tmp;
0168 } else {
0169 rv = kstrtoull(s, base, &tmp);
0170 if (rv < 0)
0171 return rv;
0172 if ((long long)tmp < 0)
0173 return -ERANGE;
0174 *res = tmp;
0175 }
0176 return 0;
0177 }
0178 EXPORT_SYMBOL(kstrtoll);
0179
0180
0181 int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
0182 {
0183 unsigned long long tmp;
0184 int rv;
0185
0186 rv = kstrtoull(s, base, &tmp);
0187 if (rv < 0)
0188 return rv;
0189 if (tmp != (unsigned long)tmp)
0190 return -ERANGE;
0191 *res = tmp;
0192 return 0;
0193 }
0194 EXPORT_SYMBOL(_kstrtoul);
0195
0196
0197 int _kstrtol(const char *s, unsigned int base, long *res)
0198 {
0199 long long tmp;
0200 int rv;
0201
0202 rv = kstrtoll(s, base, &tmp);
0203 if (rv < 0)
0204 return rv;
0205 if (tmp != (long)tmp)
0206 return -ERANGE;
0207 *res = tmp;
0208 return 0;
0209 }
0210 EXPORT_SYMBOL(_kstrtol);
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 noinline
0228 int kstrtouint(const char *s, unsigned int base, unsigned int *res)
0229 {
0230 unsigned long long tmp;
0231 int rv;
0232
0233 rv = kstrtoull(s, base, &tmp);
0234 if (rv < 0)
0235 return rv;
0236 if (tmp != (unsigned int)tmp)
0237 return -ERANGE;
0238 *res = tmp;
0239 return 0;
0240 }
0241 EXPORT_SYMBOL(kstrtouint);
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 noinline
0259 int kstrtoint(const char *s, unsigned int base, int *res)
0260 {
0261 long long tmp;
0262 int rv;
0263
0264 rv = kstrtoll(s, base, &tmp);
0265 if (rv < 0)
0266 return rv;
0267 if (tmp != (int)tmp)
0268 return -ERANGE;
0269 *res = tmp;
0270 return 0;
0271 }
0272 EXPORT_SYMBOL(kstrtoint);
0273
0274 noinline
0275 int kstrtou16(const char *s, unsigned int base, u16 *res)
0276 {
0277 unsigned long long tmp;
0278 int rv;
0279
0280 rv = kstrtoull(s, base, &tmp);
0281 if (rv < 0)
0282 return rv;
0283 if (tmp != (u16)tmp)
0284 return -ERANGE;
0285 *res = tmp;
0286 return 0;
0287 }
0288 EXPORT_SYMBOL(kstrtou16);
0289
0290 noinline
0291 int kstrtos16(const char *s, unsigned int base, s16 *res)
0292 {
0293 long long tmp;
0294 int rv;
0295
0296 rv = kstrtoll(s, base, &tmp);
0297 if (rv < 0)
0298 return rv;
0299 if (tmp != (s16)tmp)
0300 return -ERANGE;
0301 *res = tmp;
0302 return 0;
0303 }
0304 EXPORT_SYMBOL(kstrtos16);
0305
0306 noinline
0307 int kstrtou8(const char *s, unsigned int base, u8 *res)
0308 {
0309 unsigned long long tmp;
0310 int rv;
0311
0312 rv = kstrtoull(s, base, &tmp);
0313 if (rv < 0)
0314 return rv;
0315 if (tmp != (u8)tmp)
0316 return -ERANGE;
0317 *res = tmp;
0318 return 0;
0319 }
0320 EXPORT_SYMBOL(kstrtou8);
0321
0322 noinline
0323 int kstrtos8(const char *s, unsigned int base, s8 *res)
0324 {
0325 long long tmp;
0326 int rv;
0327
0328 rv = kstrtoll(s, base, &tmp);
0329 if (rv < 0)
0330 return rv;
0331 if (tmp != (s8)tmp)
0332 return -ERANGE;
0333 *res = tmp;
0334 return 0;
0335 }
0336 EXPORT_SYMBOL(kstrtos8);
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 noinline
0348 int kstrtobool(const char *s, bool *res)
0349 {
0350 if (!s)
0351 return -EINVAL;
0352
0353 switch (s[0]) {
0354 case 'y':
0355 case 'Y':
0356 case 't':
0357 case 'T':
0358 case '1':
0359 *res = true;
0360 return 0;
0361 case 'n':
0362 case 'N':
0363 case 'f':
0364 case 'F':
0365 case '0':
0366 *res = false;
0367 return 0;
0368 case 'o':
0369 case 'O':
0370 switch (s[1]) {
0371 case 'n':
0372 case 'N':
0373 *res = true;
0374 return 0;
0375 case 'f':
0376 case 'F':
0377 *res = false;
0378 return 0;
0379 default:
0380 break;
0381 }
0382 break;
0383 default:
0384 break;
0385 }
0386
0387 return -EINVAL;
0388 }
0389 EXPORT_SYMBOL(kstrtobool);
0390
0391
0392
0393
0394
0395 int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
0396 {
0397
0398 char buf[4];
0399
0400 count = min(count, sizeof(buf) - 1);
0401 if (copy_from_user(buf, s, count))
0402 return -EFAULT;
0403 buf[count] = '\0';
0404 return kstrtobool(buf, res);
0405 }
0406 EXPORT_SYMBOL(kstrtobool_from_user);
0407
0408 #define kstrto_from_user(f, g, type) \
0409 int f(const char __user *s, size_t count, unsigned int base, type *res) \
0410 { \
0411 \
0412 char buf[1 + sizeof(type) * 8 + 1 + 1]; \
0413 \
0414 count = min(count, sizeof(buf) - 1); \
0415 if (copy_from_user(buf, s, count)) \
0416 return -EFAULT; \
0417 buf[count] = '\0'; \
0418 return g(buf, base, res); \
0419 } \
0420 EXPORT_SYMBOL(f)
0421
0422 kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
0423 kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
0424 kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
0425 kstrto_from_user(kstrtol_from_user, kstrtol, long);
0426 kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
0427 kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
0428 kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
0429 kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
0430 kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
0431 kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);