1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. 4 * Copyright (C) 2007 The Regents of the University of California. 5 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 6 * Written by Brian Behlendorf <behlendorf1@llnl.gov>. 7 * UCRL-CODE-235197 8 * 9 * This file is part of the SPL, Solaris Porting Layer. 10 * 11 * The SPL is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2 of the License, or (at your 14 * option) any later version. 15 * 16 * The SPL is distributed in the hope that it will be useful, but WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 * for more details. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with the SPL. If not, see <http://www.gnu.org/licenses/>. 23 * 24 * Solaris Porting Layer (SPL) Generic Implementation. 25 */ 26 27 #include <sys/isa_defs.h> 28 #include <sys/sysmacros.h> 29 #include <sys/systeminfo.h> 30 #include <sys/vmsystm.h> 31 #include <sys/kmem.h> 32 #include <sys/kmem_cache.h> 33 #include <sys/vmem.h> 34 #include <sys/mutex.h> 35 #include <sys/rwlock.h> 36 #include <sys/taskq.h> 37 #include <sys/tsd.h> 38 #include <sys/zmod.h> 39 #include <sys/debug.h> 40 #include <sys/proc.h> 41 #include <sys/kstat.h> 42 #include <sys/file.h> 43 #include <sys/sunddi.h> 44 #include <linux/ctype.h> 45 #include <sys/disp.h> 46 #include <sys/random.h> 47 #include <sys/string.h> 48 #include <linux/kmod.h> 49 #include <linux/mod_compat.h> 50 #include <sys/cred.h> 51 #include <sys/vnode.h> 52 #include <sys/misc.h> 53 #include <linux/mod_compat.h> 54 55 unsigned long spl_hostid = 0; 56 EXPORT_SYMBOL(spl_hostid); 57 58 module_param(spl_hostid, ulong, 0644); 59 MODULE_PARM_DESC(spl_hostid, "The system hostid."); 60 61 proc_t p0; 62 EXPORT_SYMBOL(p0); 63 64 /* 65 * xoshiro256++ 1.0 PRNG by David Blackman and Sebastiano Vigna 66 * 67 * "Scrambled Linear Pseudorandom Number Generators∗" 68 * https://vigna.di.unimi.it/ftp/papers/ScrambledLinear.pdf 69 * 70 * random_get_pseudo_bytes() is an API function on Illumos whose sole purpose 71 * is to provide bytes containing random numbers. It is mapped to /dev/urandom 72 * on Illumos, which uses a "FIPS 186-2 algorithm". No user of the SPL's 73 * random_get_pseudo_bytes() needs bytes that are of cryptographic quality, so 74 * we can implement it using a fast PRNG that we seed using Linux' actual 75 * equivalent to random_get_pseudo_bytes(). We do this by providing each CPU 76 * with an independent seed so that all calls to random_get_pseudo_bytes() are 77 * free of atomic instructions. 78 * 79 * A consequence of using a fast PRNG is that using random_get_pseudo_bytes() 80 * to generate words larger than 256 bits will paradoxically be limited to 81 * `2^256 - 1` possibilities. This is because we have a sequence of `2^256 - 1` 82 * 256-bit words and selecting the first will implicitly select the second. If 83 * a caller finds this behavior undesirable, random_get_bytes() should be used 84 * instead. 85 * 86 * XXX: Linux interrupt handlers that trigger within the critical section 87 * formed by `s[3] = xp[3];` and `xp[0] = s[0];` and call this function will 88 * see the same numbers. Nothing in the code currently calls this in an 89 * interrupt handler, so this is considered to be okay. If that becomes a 90 * problem, we could create a set of per-cpu variables for interrupt handlers 91 * and use them when in_interrupt() from linux/preempt_mask.h evaluates to 92 * true. 93 */ 94 static void __percpu *spl_pseudo_entropy; 95 96 /* 97 * rotl()/spl_rand_next()/spl_rand_jump() are copied from the following CC-0 98 * licensed file: 99 * 100 * https://prng.di.unimi.it/xoshiro256plusplus.c 101 */ 102 103 static inline uint64_t rotl(const uint64_t x, int k) 104 { 105 return ((x << k) | (x >> (64 - k))); 106 } 107 108 static inline uint64_t 109 spl_rand_next(uint64_t *s) 110 { 111 const uint64_t result = rotl(s[0] + s[3], 23) + s[0]; 112 113 const uint64_t t = s[1] << 17; 114 115 s[2] ^= s[0]; 116 s[3] ^= s[1]; 117 s[1] ^= s[2]; 118 s[0] ^= s[3]; 119 120 s[2] ^= t; 121 122 s[3] = rotl(s[3], 45); 123 124 return (result); 125 } 126 127 static inline void 128 spl_rand_jump(uint64_t *s) 129 { 130 static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 131 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; 132 133 uint64_t s0 = 0; 134 uint64_t s1 = 0; 135 uint64_t s2 = 0; 136 uint64_t s3 = 0; 137 int i, b; 138 for (i = 0; i < sizeof (JUMP) / sizeof (*JUMP); i++) 139 for (b = 0; b < 64; b++) { 140 if (JUMP[i] & 1ULL << b) { 141 s0 ^= s[0]; 142 s1 ^= s[1]; 143 s2 ^= s[2]; 144 s3 ^= s[3]; 145 } 146 (void) spl_rand_next(s); 147 } 148 149 s[0] = s0; 150 s[1] = s1; 151 s[2] = s2; 152 s[3] = s3; 153 } 154 155 int 156 random_get_pseudo_bytes(uint8_t *ptr, size_t len) 157 { 158 uint64_t *xp, s[4]; 159 160 ASSERT(ptr); 161 162 xp = get_cpu_ptr(spl_pseudo_entropy); 163 164 s[0] = xp[0]; 165 s[1] = xp[1]; 166 s[2] = xp[2]; 167 s[3] = xp[3]; 168 169 while (len) { 170 union { 171 uint64_t ui64; 172 uint8_t byte[sizeof (uint64_t)]; 173 }entropy; 174 int i = MIN(len, sizeof (uint64_t)); 175 176 len -= i; 177 entropy.ui64 = spl_rand_next(s); 178 179 /* 180 * xoshiro256++ has low entropy lower bytes, so we copy the 181 * higher order bytes first. 182 */ 183 while (i--) 184 #ifdef _ZFS_BIG_ENDIAN 185 *ptr++ = entropy.byte[i]; 186 #else 187 *ptr++ = entropy.byte[7 - i]; 188 #endif 189 } 190 191 xp[0] = s[0]; 192 xp[1] = s[1]; 193 xp[2] = s[2]; 194 xp[3] = s[3]; 195 196 put_cpu_ptr(spl_pseudo_entropy); 197 198 return (0); 199 } 200 EXPORT_SYMBOL(random_get_pseudo_bytes); 201 202 /* 203 * NOTE: The strtoxx behavior is solely based on my reading of the Solaris 204 * ddi_strtol(9F) man page. I have not verified the behavior of these 205 * functions against their Solaris counterparts. It is possible that I 206 * may have misinterpreted the man page or the man page is incorrect. 207 */ 208 int ddi_strtol(const char *, char **, int, long *); 209 int ddi_strtoull(const char *, char **, int, unsigned long long *); 210 int ddi_strtoll(const char *, char **, int, long long *); 211 212 #define define_ddi_strtox(type, valtype) \ 213 int ddi_strto##type(const char *str, char **endptr, \ 214 int base, valtype *result) \ 215 { \ 216 valtype last_value, value = 0; \ 217 char *ptr = (char *)str; \ 218 int digit, minus = 0; \ 219 \ 220 while (strchr(" \t\n\r\f", *ptr)) \ 221 ++ptr; \ 222 \ 223 if (strlen(ptr) == 0) \ 224 return (EINVAL); \ 225 \ 226 switch (*ptr) { \ 227 case '-': \ 228 minus = 1; \ 229 zfs_fallthrough; \ 230 case '+': \ 231 ++ptr; \ 232 break; \ 233 } \ 234 \ 235 /* Auto-detect base based on prefix */ \ 236 if (!base) { \ 237 if (str[0] == '0') { \ 238 if (tolower(str[1]) == 'x' && isxdigit(str[2])) { \ 239 base = 16; /* hex */ \ 240 ptr += 2; \ 241 } else if (str[1] >= '0' && str[1] < '8') { \ 242 base = 8; /* octal */ \ 243 ptr += 1; \ 244 } else { \ 245 return (EINVAL); \ 246 } \ 247 } else { \ 248 base = 10; /* decimal */ \ 249 } \ 250 } \ 251 \ 252 while (1) { \ 253 if (isdigit(*ptr)) \ 254 digit = *ptr - '0'; \ 255 else if (isalpha(*ptr)) \ 256 digit = tolower(*ptr) - 'a' + 10; \ 257 else \ 258 break; \ 259 \ 260 if (digit >= base) \ 261 break; \ 262 \ 263 last_value = value; \ 264 value = value * base + digit; \ 265 if (last_value > value) /* Overflow */ \ 266 return (ERANGE); \ 267 \ 268 ptr++; \ 269 } \ 270 \ 271 *result = minus ? -value : value; \ 272 \ 273 if (endptr) \ 274 *endptr = ptr; \ 275 \ 276 return (0); \ 277 } \ 278 279 define_ddi_strtox(l, long) 280 define_ddi_strtox(ull, unsigned long long) 281 define_ddi_strtox(ll, long long) 282 283 EXPORT_SYMBOL(ddi_strtol); 284 EXPORT_SYMBOL(ddi_strtoll); 285 EXPORT_SYMBOL(ddi_strtoull); 286 287 int 288 ddi_copyin(const void *from, void *to, size_t len, int flags) 289 { 290 /* Fake ioctl() issued by kernel, 'from' is a kernel address */ 291 if (flags & FKIOCTL) { 292 memcpy(to, from, len); 293 return (0); 294 } 295 296 return (copyin(from, to, len)); 297 } 298 EXPORT_SYMBOL(ddi_copyin); 299 300 /* 301 * Post a uevent to userspace whenever a new vdev adds to the pool. It is 302 * necessary to sync blkid information with udev, which zed daemon uses 303 * during device hotplug to identify the vdev. 304 */ 305 void 306 spl_signal_kobj_evt(struct block_device *bdev) 307 { 308 #if defined(HAVE_BDEV_KOBJ) || defined(HAVE_PART_TO_DEV) 309 #ifdef HAVE_BDEV_KOBJ 310 struct kobject *disk_kobj = bdev_kobj(bdev); 311 #else 312 struct kobject *disk_kobj = &part_to_dev(bdev->bd_part)->kobj; 313 #endif 314 if (disk_kobj) { 315 int ret = kobject_uevent(disk_kobj, KOBJ_CHANGE); 316 if (ret) { 317 pr_warn("ZFS: Sending event '%d' to kobject: '%s'" 318 " (%p): failed(ret:%d)\n", KOBJ_CHANGE, 319 kobject_name(disk_kobj), disk_kobj, ret); 320 } 321 } 322 #else 323 /* 324 * This is encountered if neither bdev_kobj() nor part_to_dev() is available 325 * in the kernel - likely due to an API change that needs to be chased down. 326 */ 327 #error "Unsupported kernel: unable to get struct kobj from bdev" 328 #endif 329 } 330 EXPORT_SYMBOL(spl_signal_kobj_evt); 331 332 int 333 ddi_copyout(const void *from, void *to, size_t len, int flags) 334 { 335 /* Fake ioctl() issued by kernel, 'from' is a kernel address */ 336 if (flags & FKIOCTL) { 337 memcpy(to, from, len); 338 return (0); 339 } 340 341 return (copyout(from, to, len)); 342 } 343 EXPORT_SYMBOL(ddi_copyout); 344 345 static int 346 spl_getattr(struct file *filp, struct kstat *stat) 347 { 348 int rc; 349 350 ASSERT(filp); 351 ASSERT(stat); 352 353 rc = vfs_getattr(&filp->f_path, stat, STATX_BASIC_STATS, 354 AT_STATX_SYNC_AS_STAT); 355 if (rc) 356 return (-rc); 357 358 return (0); 359 } 360 361 /* 362 * Read the unique system identifier from the /etc/hostid file. 363 * 364 * The behavior of /usr/bin/hostid on Linux systems with the 365 * regular eglibc and coreutils is: 366 * 367 * 1. Generate the value if the /etc/hostid file does not exist 368 * or if the /etc/hostid file is less than four bytes in size. 369 * 370 * 2. If the /etc/hostid file is at least 4 bytes, then return 371 * the first four bytes [0..3] in native endian order. 372 * 373 * 3. Always ignore bytes [4..] if they exist in the file. 374 * 375 * Only the first four bytes are significant, even on systems that 376 * have a 64-bit word size. 377 * 378 * See: 379 * 380 * eglibc: sysdeps/unix/sysv/linux/gethostid.c 381 * coreutils: src/hostid.c 382 * 383 * Notes: 384 * 385 * The /etc/hostid file on Solaris is a text file that often reads: 386 * 387 * # DO NOT EDIT 388 * "0123456789" 389 * 390 * Directly copying this file to Linux results in a constant 391 * hostid of 4f442023 because the default comment constitutes 392 * the first four bytes of the file. 393 * 394 */ 395 396 static char *spl_hostid_path = HW_HOSTID_PATH; 397 module_param(spl_hostid_path, charp, 0444); 398 MODULE_PARM_DESC(spl_hostid_path, "The system hostid file (/etc/hostid)"); 399 400 static int 401 hostid_read(uint32_t *hostid) 402 { 403 uint64_t size; 404 uint32_t value = 0; 405 int error; 406 loff_t off; 407 struct file *filp; 408 struct kstat stat; 409 410 filp = filp_open(spl_hostid_path, 0, 0); 411 412 if (IS_ERR(filp)) 413 return (ENOENT); 414 415 error = spl_getattr(filp, &stat); 416 if (error) { 417 filp_close(filp, 0); 418 return (error); 419 } 420 size = stat.size; 421 // cppcheck-suppress sizeofwithnumericparameter 422 if (size < sizeof (HW_HOSTID_MASK)) { 423 filp_close(filp, 0); 424 return (EINVAL); 425 } 426 427 off = 0; 428 /* 429 * Read directly into the variable like eglibc does. 430 * Short reads are okay; native behavior is preserved. 431 */ 432 error = kernel_read(filp, &value, sizeof (value), &off); 433 if (error < 0) { 434 filp_close(filp, 0); 435 return (EIO); 436 } 437 438 /* Mask down to 32 bits like coreutils does. */ 439 *hostid = (value & HW_HOSTID_MASK); 440 filp_close(filp, 0); 441 442 return (0); 443 } 444 445 /* 446 * Return the system hostid. Preferentially use the spl_hostid module option 447 * when set, otherwise use the value in the /etc/hostid file. 448 */ 449 uint32_t 450 zone_get_hostid(void *zone) 451 { 452 uint32_t hostid; 453 454 ASSERT0P(zone); 455 456 if (spl_hostid != 0) 457 return ((uint32_t)(spl_hostid & HW_HOSTID_MASK)); 458 459 if (hostid_read(&hostid) == 0) 460 return (hostid); 461 462 return (0); 463 } 464 EXPORT_SYMBOL(zone_get_hostid); 465 466 static int 467 spl_kvmem_init(void) 468 { 469 int rc = 0; 470 471 rc = spl_kmem_init(); 472 if (rc) 473 return (rc); 474 475 rc = spl_vmem_init(); 476 if (rc) { 477 spl_kmem_fini(); 478 return (rc); 479 } 480 481 return (rc); 482 } 483 484 /* 485 * We initialize the random number generator with 128 bits of entropy from the 486 * system random number generator. In the improbable case that we have a zero 487 * seed, we fallback to the system jiffies, unless it is also zero, in which 488 * situation we use a preprogrammed seed. We step forward by 2^64 iterations to 489 * initialize each of the per-cpu seeds so that the sequences generated on each 490 * CPU are guaranteed to never overlap in practice. 491 */ 492 static int __init 493 spl_random_init(void) 494 { 495 uint64_t s[4]; 496 int i = 0; 497 498 spl_pseudo_entropy = __alloc_percpu(4 * sizeof (uint64_t), 499 sizeof (uint64_t)); 500 501 if (!spl_pseudo_entropy) 502 return (-ENOMEM); 503 504 get_random_bytes(s, sizeof (s)); 505 506 if (s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0) { 507 if (jiffies != 0) { 508 s[0] = jiffies; 509 s[1] = ~0 - jiffies; 510 s[2] = ~jiffies; 511 s[3] = jiffies - ~0; 512 } else { 513 (void) memcpy(s, "improbable seed", 16); 514 } 515 printk("SPL: get_random_bytes() returned 0 " 516 "when generating random seed. Setting initial seed to " 517 "0x%016llx%016llx%016llx%016llx.\n", cpu_to_be64(s[0]), 518 cpu_to_be64(s[1]), cpu_to_be64(s[2]), cpu_to_be64(s[3])); 519 } 520 521 for_each_possible_cpu(i) { 522 uint64_t *wordp = per_cpu_ptr(spl_pseudo_entropy, i); 523 524 spl_rand_jump(s); 525 526 wordp[0] = s[0]; 527 wordp[1] = s[1]; 528 wordp[2] = s[2]; 529 wordp[3] = s[3]; 530 } 531 532 return (0); 533 } 534 535 static void 536 spl_random_fini(void) 537 { 538 free_percpu(spl_pseudo_entropy); 539 } 540 541 static void 542 spl_kvmem_fini(void) 543 { 544 spl_vmem_fini(); 545 spl_kmem_fini(); 546 } 547 548 static int __init 549 spl_init(void) 550 { 551 int rc = 0; 552 553 if ((rc = spl_random_init())) 554 goto out0; 555 556 if ((rc = spl_kvmem_init())) 557 goto out1; 558 559 if ((rc = spl_tsd_init())) 560 goto out2; 561 562 if ((rc = spl_proc_init())) 563 goto out3; 564 565 if ((rc = spl_kstat_init())) 566 goto out4; 567 568 if ((rc = spl_taskq_init())) 569 goto out5; 570 571 if ((rc = spl_kmem_cache_init())) 572 goto out6; 573 574 if ((rc = spl_zlib_init())) 575 goto out7; 576 577 if ((rc = spl_zone_init())) 578 goto out8; 579 580 return (rc); 581 582 out8: 583 spl_zlib_fini(); 584 out7: 585 spl_kmem_cache_fini(); 586 out6: 587 spl_taskq_fini(); 588 out5: 589 spl_kstat_fini(); 590 out4: 591 spl_proc_fini(); 592 out3: 593 spl_tsd_fini(); 594 out2: 595 spl_kvmem_fini(); 596 out1: 597 spl_random_fini(); 598 out0: 599 return (rc); 600 } 601 602 static void __exit 603 spl_fini(void) 604 { 605 spl_zone_fini(); 606 spl_zlib_fini(); 607 spl_kmem_cache_fini(); 608 spl_taskq_fini(); 609 spl_kstat_fini(); 610 spl_proc_fini(); 611 spl_tsd_fini(); 612 spl_kvmem_fini(); 613 spl_random_fini(); 614 } 615 616 module_init(spl_init); 617 module_exit(spl_fini); 618 619 MODULE_DESCRIPTION("Solaris Porting Layer"); 620 MODULE_AUTHOR(ZFS_META_AUTHOR); 621 MODULE_LICENSE("GPL"); 622 MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE); 623