* 'android-4.9-q' of https://android.googlesource.com/kernel/common: Linux 4.9.284 sctp: validate from_addr_param return drm/nouveau/nvkm: Replace -ENOSYS with -ENODEV blk-throttle: fix UAF by deleteing timer in blk_throtl_exit() nilfs2: fix memory leak in nilfs_sysfs_delete_snapshot_group nilfs2: fix memory leak in nilfs_sysfs_create_snapshot_group nilfs2: fix memory leak in nilfs_sysfs_delete_##name##_group nilfs2: fix memory leak in nilfs_sysfs_create_##name##_group nilfs2: fix NULL pointer in nilfs_##name##_attr_release nilfs2: fix memory leak in nilfs_sysfs_create_device_group ceph: lockdep annotations for try_nonblocking_invalidate dmaengine: xilinx_dma: Set DMA mask for coherent APIs dmaengine: ioat: depends on !UML parisc: Move pci_dev_is_behind_card_dino to where it is used pwm: lpc32xx: Don't modify HW state in .probe() after the PWM chip was registered profiling: fix shift-out-of-bounds bugs prctl: allow to setup brk for et_dyn executables 9p/trans_virtio: Remove sysfs file on probe failure thermal/drivers/exynos: Fix an error code in exynos_tmu_probe() dmaengine: acpi: Avoid comparison GSI with Linux vIRQ sctp: add param size validation for SCTP_PARAM_SET_PRIMARY sctp: validate chunk size in __rcv_asconf_lookup staging: android: ion: fix page is NULL crypto: talitos - fix max key size for sha384 and sha512 PM / wakeirq: Fix unbalanced IRQ enable for wakeirq s390/bpf: Fix optimizing out zero-extensions Linux 4.9.283 s390/bpf: Fix 64-bit subtraction of the -0x80000000 constant net: renesas: sh_eth: Fix freeing wrong tx descriptor qlcnic: Remove redundant unlock in qlcnic_pinit_from_rom net: dsa: b53: Fix calculating number of switch ports ARC: export clear_user_page() for modules mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()' PCI: Sync __pci_register_driver() stub for CONFIG_PCI=n ethtool: Fix an error code in cxgb2.c net: usb: cdc_mbim: avoid altsetting toggling for Telit LN920 mfd: Don't use irq_create_mapping() to resolve a mapping dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation x86/mm: Fix kern_addr_valid() to cope with existing but not present entries tcp: fix tp->undo_retrans accounting in tcp_sacktag_one() net/af_unix: fix a data-race in unix_dgram_poll events: Reuse value read using READ_ONCE instead of re-reading it tipc: increase timeout in tipc_sk_enqueue() r6040: Restore MDIO clock frequency after MAC reset net/l2tp: Fix reference count leak in l2tp_udp_recv_core dccp: don't duplicate ccid when cloning dccp sock ptp: dp83640: don't define PAGE0 net-caif: avoid user-triggerable WARN_ON(1) bnx2x: Fix enabling network interfaces without VFs xen: reset legacy rtc flag for PV domU platform/chrome: cros_ec_proto: Send command again when timeout occurs memcg: enable accounting for pids in nested pid namespaces mm/hugetlb: initialize hugetlb_usage in mm_init scsi: BusLogic: Fix missing pr_cont() use parisc: fix crash with signals and alloca net: w5100: check return value after calling platform_get_resource() net: fix NULL pointer reference in cipso_v4_doi_free ath9k: fix sleeping in atomic context ath9k: fix OOB read ar9300_eeprom_restore_internal parport: remove non-zero check on count usbip: give back URBs for unsent unlink requests during cleanup Revert "USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set" cifs: fix wrong release in sess_alloc_buffer() failed path mmc: rtsx_pci: Fix long reads when clock is prescaled gfs2: Don't call dlm after protocol is unmounted rpc: fix gss_svc_init cleanup on failure ARM: tegra: tamonten: Fix UART pad setting gpu: drm: amd: amdgpu: amdgpu_i2c: fix possible uninitialized-variable access in amdgpu_i2c_router_select_ddc_port() Bluetooth: avoid circular locks in sco_sock_connect net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe() ASoC: Intel: bytcr_rt5640: Move "Platform Clock" routes to the maps for the matching in-/output Bluetooth: skip invalid hci_sync_conn_complete_evt ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init() staging: ks7010: Fix the initialization of the 'sleep_status' structure serial: 8250_pci: make setup_port() parameters explicitly unsigned hvsi: don't panic on tty_register_driver failure xtensa: ISS: don't panic in rs_init serial: 8250: Define RX trigger levels for OxSemi 950 devices s390/jump_label: print real address in a case of a jump label bug flow_dissector: Fix out-of-bounds warnings ipv4: ip_output.c: Fix out-of-bounds warning in ip_copy_addrs() video: fbdev: riva: Error out if 'pixclock' equals zero video: fbdev: kyro: Error out if 'pixclock' equals zero video: fbdev: asiliantfb: Error out if 'pixclock' equals zero bpf/tests: Do not PASS tests without actually testing the result bpf/tests: Fix copy-and-paste error in double word test tty: serial: jsm: hold port lock when reporting modem line changes staging: board: Fix uninitialized spinlock when attaching genpd usb: gadget: composite: Allow bMaxPower=0 if self-powered usb: gadget: u_ether: fix a potential null pointer dereference usb: host: fotg210: fix the actual_length of an iso packet usb: host: fotg210: fix the endpoint's transactional opportunities calculation Smack: Fix wrong semantics in smk_access_entry() netlink: Deal with ESRCH error in nlmsg_notify() video: fbdev: kyro: fix a DoS bug by restricting user input iio: dac: ad5624r: Fix incorrect handling of an optional regulator. PCI: Use pci_update_current_state() in pci_enable_device_flags() crypto: mxs-dcp - Use sg_mapping_iter to copy data MIPS: Malta: fix alignment of the devicetree buffer pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry() openrisc: don't printk() unconditionally vfio: Use config not menuconfig for VFIO_NOIOMMU PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported ARM: 9105/1: atags_to_fdt: don't warn about stack size libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs media: rc-loopback: return number of emitters rather than error media: uvc: don't do DMA on stack VMCI: fix NULL pointer dereference when unmapping queue pair power: supply: max17042: handle fails of reading status register crypto: public_key: fix overflow during implicit conversion xen: fix setting of max_pfn in shared_info powerpc/perf/hv-gpci: Fix counter value parsing PCI/MSI: Skip masking MSI-X on Xen PV rtc: tps65910: Correct driver module alias fbmem: don't allow too huge resolutions clk: kirkwood: Fix a clocking boot regression IMA: remove -Wmissing-prototypes warning KVM: x86: Update vCPU's hv_clock before back to guest when tsc_offset is adjusted tty: Fix data race between tiocsti() and flush_to_ldisc() ipv4: make exception cache less predictible bcma: Fix memory leak for internally-handled cores ath6kl: wmi: fix an error code in ath6kl_wmi_sync_point() usb: ehci-orion: Handle errors of clk_prepare_enable() in probe i2c: mt65xx: fix IRQ check CIFS: Fix a potencially linear read overflow mmc: moxart: Fix issue with uninitialized dma_slave_config mmc: dw_mmc: Fix issue with uninitialized dma_slave_config i2c: s3c2410: fix IRQ check i2c: iop3xx: fix deferred probing Bluetooth: add timeout sanity check to hci_inquiry usb: gadget: mv_u3d: request_irq() after initializing UDC usb: phy: tahvo: add IRQ check usb: host: ohci-tmio: add IRQ check Bluetooth: Move shutdown callback before flushing tx and rx queue usb: phy: twl6030: add IRQ checks usb: phy: fsl-usb: add IRQ check usb: gadget: udc: at91: add IRQ check drm/msm/dsi: Fix some reference counted resource leaks Bluetooth: fix repeated calls to sco_sock_kill arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 Bluetooth: increase BTNAMSIZ to 21 chars to fix potential buffer overflow soc: qcom: smsm: Fix missed interrupts if state changes while masked PCI: PM: Enable PME if it can be signaled from D3cold i2c: highlander: add IRQ check net: cipso: fix warnings in netlbl_cipsov4_add_std tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos Bluetooth: sco: prevent information leak in sco_conn_defer_accept() media: go7007: remove redundant initialization media: dvb-usb: fix uninit-value in vp702x_read_mac_addr media: dvb-usb: fix uninit-value in dvb_usb_adapter_dvb_init certs: Trigger creation of RSA module signing key if it's not an RSA key crypto: qat - use proper type for vf_mask spi: spi-pic32: Fix issue with uninitialized dma_slave_config m68k: emu: Fix invalid free in nfeth_cleanup() udf_get_extendedattr() had no boundary checks. crypto: qat - do not export adf_iov_putmsg() crypto: qat - fix naming for init/shutdown VF to PF notifications crypto: qat - fix reuse of completion variable crypto: qat - handle both source of interrupt in VF ISR crypto: qat - do not ignore errors from enable_vf2pf_comms() libata: fix ata_host_start() power: supply: max17042_battery: fix typo in MAx17042_TOFF udf: Check LVID earlier crypto: omap-sham - clear dma flags only after omap_sham_update_dma_stop() power: supply: axp288_fuel_gauge: Report register-address on readb / writeb errors crypto: mxs-dcp - Check for DMA mapping errors regmap: fix the offset of register error log PCI: Call Max Payload Size-related fixup quirks early x86/reboot: Limit Dell Optiplex 990 quirk to early BIOS versions Revert "btrfs: compression: don't try to compress if we don't have enough pages" mm/page_alloc: speed up the iteration of max_order net: ll_temac: Remove left-over debug message powerpc/boot: Delete unneeded .globl _zimage_start powerpc/module64: Fix comment in R_PPC64_ENTRY handling crypto: talitos - reduce max key size for SEC1 mm/kmemleak.c: make cond_resched() rate-limiting more efficient s390/disassembler: correct disassembly lines alignment ipv4/icmp: l3mdev: Perform icmp error route lookup on source device routing table (v2) gfs2: Don't clear SGID when inheriting ACLs nvme-pci: Fix an error handling path in 'nvme_probe()' tc358743: fix register i2c_rd/wr function fix PM / wakeirq: Enable dedicated wakeirq for suspend net/sched: cls_flower: Use mask for addr_type USB: serial: mos7720: improve OOM-handling in read_mos_reg() usb: phy: isp1301: Fix build warning when CONFIG_OF is disabled igmp: Add ip_mc_list lock in ip_check_mc_rcu media: stkwebcam: fix memory leak in stk_camera_probe ath9k: Postpone key cache entry deletion for TXQ frames reference it ath: Modify ath_key_delete() to not need full key entry ath: Export ath_hw_keysetmac() ath9k: Clear key cache explicitly on disabling hardware ath: Use safer key clearing with key cache entries ALSA: pcm: fix divide error in snd_pcm_lib_ioctl ARM: 8918/2: only build return_address() if needed cryptoloop: add a deprecation warning perf/x86/amd/ibs: Work around erratum #1197 qede: Fix memset corruption qed: Fix the VF msix vectors flow xtensa: fix kconfig unmet dependency warning for HAVE_FUTEX_CMPXCHG mtd: nand: atmel_nand: remove build warning in atmel_nand_remove() ext4: fix race writing to an inline_data file while its xattrs are changing Linux 4.9.282 Revert "floppy: reintroduce O_NDELAY fix" KVM: x86/mmu: Treat NX as used (not reserved) for all !TDP shadow MMUs fbmem: add margin check to fb_check_caps() vt_kdsetmode: extend console locking net/rds: dma_map_sg is entitled to merge entries vringh: Use wiov->used to check for read/write desc order virtio: Improve vq->broken access to avoid any compiler optimization net: marvell: fix MVNETA_TX_IN_PRGRS bit number ip_gre: add validation for csum_start e1000e: Fix the max snoop/no-snoop latency for 10M IB/hfi1: Fix possible null-pointer dereference in _extend_sdma_tx_descs() usb: dwc3: gadget: Fix dwc3_calc_trbs_left() USB: serial: option: add new VID/PID to support Fibocom FG150 Revert "USB: serial: ch341: fix character loss at high transfer rates" can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX and TX error counters ARC: Fix CONFIG_STACKDEPOT Linux 4.9.281 fs: warn about impending deprecation of mandatory locks locks: print a warning when mount fails due to lack of "mand" support ASoC: intel: atom: Fix breakage for PCM buffer address setup btrfs: prevent rename2 from exchanging a subvol with a directory from different parents ipack: tpci200: fix many double free issues in tpci200_pci_probe ALSA: hda - fix the 'Capture Switch' value change notifications mmc: dw_mmc: Fix hang on data CRC error mmc: dw_mmc: call the dw_mci_prep_stop_abort() by default net: qlcnic: add missed unlock in qlcnic_83xx_flash_read32 net: 6pack: fix slab-out-of-bounds in decode_data vhost: Fix the calculation in vhost_overflow() dccp: add do-while-0 stubs for dccp_pr_debug macros Bluetooth: hidp: use correct wait queue when removing ctrl_wait ARM: dts: nomadik: Fix up interrupt controller node names scsi: core: Avoid printing an error if target_alloc() returns -ENXIO scsi: scsi_dh_rdac: Avoid crash during rdac_bus_attach() scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry() dmaengine: of-dma: router_xlate to return -EPROBE_DEFER if controller is not yet available ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218 dmaengine: usb-dmac: Fix PM reference leak in usb_dmac_probe() x86/fpu: Make init_fpstate correct with optimized XSAVE KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl (CVE-2021-3653) mac80211: drop data frames without key on encrypted links vmlinux.lds.h: Handle clang's module.{c,d}tor sections PCI/MSI: Enforce MSI[X] entry updates to be visible PCI/MSI: Enforce that MSI-X table entry is masked for update PCI/MSI: Mask all unused MSI-X entries PCI/MSI: Protect msi_desc::masked for multi-MSI PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown() PCI/MSI: Correct misleading comments PCI/MSI: Do not set invalid bits in MSI mask PCI/MSI: Enable and mask MSI-X early x86/tools: Fix objdump version check again xen/events: Fix race in set_evtchn_to_irq tcp_bbr: fix u32 wrap bug in round logic if bbr_init() called after 2B packets net: bridge: fix memleak in br_add_if() net: Fix memory leak in ieee802154_raw_deliver ppp: Fix generating ifname when empty IFLA_IFNAME is specified ACPI: NFIT: Fix support for virtual SPA ranges i2c: dev: zero out array used for i2c reads from userspace ASoC: intel: atom: Fix reference to PCM buffer address iio: adc: Fix incorrect exit of for-loop ANDROID: xt_quota2: set usersize in xt_match registration object ANDROID: xt_quota2: clear quota2_log message before sending ANDROID: xt_quota2: remove trailing junk which might have a digit in it UPSTREAM: netfilter: x_tables: fix pointer leaks to userspace Linux 4.9.280 ovl: prevent private clone if bind mount is not allowed net: xilinx_emaclite: Do not print real IOMEM pointer ppp: Fix generating ppp unit id when ifname is not specified USB:ehci:fix Kunpeng920 ehci hardware problem net/qla3xxx: fix schedule while atomic in ql_wait_for_drvr_lock and ql_adapter_reset alpha: Send stop IPI to send to online CPUs reiserfs: check directory items on read from disk reiserfs: add check for root_inode in reiserfs_fill_super perf/x86/amd: Don't touch the AMD64_EVENTSEL_HOSTONLY bit inside the guest pcmcia: i82092: fix a null pointer dereference bug MIPS: Malta: Do not byte-swap accesses to the CBUS UART serial: 8250: Mask out floating 16/32-bit bus bits pipe: increase minimum default pipe size to 2 pages media: rtl28xxu: fix zero-length control request scripts/tracing: fix the bug that can't parse raw_trace_func usb: otg-fsm: Fix hrtimer list corruption USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2 USB: serial: ch341: fix character loss at high transfer rates USB: serial: option: add Telit FD980 composition 0x1056 USB: usbtmc: Fix RCU stall warning Bluetooth: defer cleanup of resources in hci_unregister_dev() net: vxge: fix use-after-free in vxge_device_unregister net: fec: fix use-after-free in fec_drv_remove net: pegasus: fix uninit-value in get_interrupt_interval bnx2x: fix an error code in bnx2x_nic_load() mips: Fix non-POSIX regexp net: natsemi: Fix missing pci_disable_device() in probe and remove media: videobuf2-core: dequeue if start_streaming fails scsi: sr: Return correct event when media event code is 3 ALSA: seq: Fix racy deletion of subscriber ANDROID: staging: ion: move buffer kmap from begin/end_cpu_access() Linux 4.9.279 spi: mediatek: Fix fifo transfer can: raw: raw_setsockopt(): fix raw_rcv panic for sock UAF Revert "Bluetooth: Shutdown controller after workqueues are flushed or cancelled" net: Fix zero-copy head len calculation. r8152: Fix potential PM refcount imbalance regulator: rt5033: Fix n_voltages settings for BUCK and LDO btrfs: mark compressed range uptodate only if all bio succeed Linux 4.9.278 sis900: Fix missing pci_disable_device() in probe and remove tulip: windbond-840: Fix missing pci_disable_device() in probe and remove net/mlx5: Fix flow table chaining net: llc: fix skb_over_panic mlx4: Fix missing error code in mlx4_load_one() tipc: fix sleeping in tipc accept routine netfilter: nft_nat: allow to specify layer 4 protocol NAT only netfilter: conntrack: adjust stop timestamp to real expiry value cfg80211: Fix possible memory leak in function cfg80211_bss_update x86/asm: Ensure asm/proto.h can be included stand-alone nfc: nfcsim: fix use after free during module unload NIU: fix incorrect error return, missed in previous revert can: esd_usb2: fix memory leak can: ems_usb: fix memory leak can: usb_8dev: fix memory leak ocfs2: issue zeroout to EOF blocks ocfs2: fix zero out valid data x86/kvm: fix vcpu-id indexed array sizes ARM: ensure the signal page contains defined contents lib/string.c: add multibyte memset functions ARM: dts: versatile: Fix up interrupt controller node names hfs: add lock nesting notation to hfs_find_init hfs: fix high memory mapping in hfs_bnode_read hfs: add missing clean-up in hfs_fill_super sctp: move 198 addresses from unusable to private scope net/802/garp: fix memleak in garp_request_join() net/802/mrp: fix memleak in mrp_request_join() workqueue: fix UAF in pwq_unbound_release_workfn() af_unix: fix garbage collect vs MSG_PEEK net: split out functions related to registering inflight socket files tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca Linux 4.9.277 btrfs: compression: don't try to compress if we don't have enough pages iio: accel: bma180: Fix BMA25x bandwidth register values iio: accel: bma180: Use explicit member assignment net: bcmgenet: ensure EXT_ENERGY_DET_MASK is clear media: ngene: Fix out-of-bounds bug in ngene_command_config_free_buf() tracing: Fix bug in rb_per_cpu_empty() that might cause deadloop. USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick USB: serial: cp210x: fix comments for GE CS1000 USB: serial: option: add support for u-blox LARA-R6 family usb: renesas_usbhs: Fix superfluous irqs happen after usb_pkt_pop() usb: max-3421: Prevent corruption of freed memory USB: usb-storage: Add LaCie Rugged USB3-FW to IGNORE_UAS usb: hub: Disable USB 3 device initiated lpm if exit latency is too high KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow xhci: Fix lost USB 2 remote wake ALSA: sb: Fix potential ABBA deadlock in CSP driver s390/ftrace: fix ftrace_update_ftrace_func implementation Revert "MIPS: add PMD table accounting into MIPS'pmd_alloc_one" proc: Avoid mixing integer types in mem_rw() Revert "USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem" scsi: target: Fix protect handling in WRITE SAME(32) scsi: iscsi: Fix iface sysfs attr detection netrom: Decrease sock refcount when sock timers expire net: decnet: Fix sleeping inside in af_decnet net: fix uninit-value in caif_seqpkt_sendmsg s390/bpf: Perform r1 range checking before accessing jit->seen_reg[r1] spi: mediatek: fix fifo rx mode perf probe-file: Delete namelist in del_events() on the error path perf test bpf: Free obj_buf perf lzma: Close lzma stream on exit igb: Check if num of q_vectors is smaller than max before array access iavf: Fix an error handling path in 'iavf_probe()' e1000e: Fix an error handling path in 'e1000_probe()' fm10k: Fix an error handling path in 'fm10k_probe()' igb: Fix an error handling path in 'igb_probe()' ixgbe: Fix an error handling path in 'ixgbe_probe()' ipv6: tcp: drop silly ICMPv6 packet too big messages tcp: annotate data races around tp->mtu_info net: validate lwtstate->data before returning from skb_tunnel_info() net: ti: fix UAF in tlan_remove_one net: qcom/emac: fix UAF in emac_remove net: moxa: fix UAF in moxart_mac_probe net: bcmgenet: Ensure all TX/RX queues DMAs are disabled net: bridge: sync fdb to new unicast-filtering ports net: ipv6: fix return value of ip6_skb_dst_mtu sched/fair: Fix CFS bandwidth hrtimer expiry type scsi: aic7xxx: Fix unintentional sign extension issue on left shift of u8 rtc: max77686: Do not enforce (incorrect) interrupt trigger type kbuild: mkcompile_h: consider timestamp if KBUILD_BUILD_TIMESTAMP is set thermal/core: Correct function name thermal_zone_device_unregister() arm64: dts: juno: Update SCPI nodes as per the YAML schema ARM: dts: stm32: fix RCC node name on stm32f429 MCU ARM: imx: pm-imx5: Fix references to imx5_cpu_suspend_info ARM: dts: imx6: phyFLEX: Fix UART hardware flow control ARM: dts: BCM63xx: Fix NAND nodes names ARM: brcmstb: dts: fix NAND nodes names reset: ti-syscon: fix to_ti_syscon_reset_data macro ARM: dts: rockchip: Fix power-controller node names for rk3288 ARM: dts: rockchip: fix pinctrl sleep nodename for rk3036-kylin and rk3288 ANDROID: selinux: modify RTM_GETNEIGH{TBL} Conflicts: drivers/staging/android/ion/ion_system_heap.c drivers/usb/dwc3/gadget.c fs/gfs2/acl.c net/netfilter/xt_quota2.c Change-Id: I7ffad69c707b6df7e80e6ed9f232a996ed785fbe
1105 lines
24 KiB
C
1105 lines
24 KiB
C
/*
|
|
* linux/lib/string.c
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
*/
|
|
|
|
/*
|
|
* stupid library routines.. The optimized versions should generally be found
|
|
* as inline code in <asm-xx/string.h>
|
|
*
|
|
* These are buggy as well..
|
|
*
|
|
* * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
|
|
* - Added strsep() which will replace strtok() soon (because strsep() is
|
|
* reentrant and should be faster). Use only strsep() in new code, please.
|
|
*
|
|
* * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
|
|
* Matthew Hawkins <matt@mh.dropbear.id.au>
|
|
* - Kissed strtok() goodbye
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/string.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/export.h>
|
|
#include <linux/bug.h>
|
|
#include <linux/errno.h>
|
|
|
|
#include <asm/byteorder.h>
|
|
#include <asm/word-at-a-time.h>
|
|
#include <asm/page.h>
|
|
|
|
#ifndef __HAVE_ARCH_STRNCASECMP
|
|
/**
|
|
* strncasecmp - Case insensitive, length-limited string comparison
|
|
* @s1: One string
|
|
* @s2: The other string
|
|
* @len: the maximum number of characters to compare
|
|
*/
|
|
int strncasecmp(const char *s1, const char *s2, size_t len)
|
|
{
|
|
/* Yes, Virginia, it had better be unsigned */
|
|
unsigned char c1, c2;
|
|
|
|
if (!len)
|
|
return 0;
|
|
|
|
do {
|
|
c1 = *s1++;
|
|
c2 = *s2++;
|
|
if (!c1 || !c2)
|
|
break;
|
|
if (c1 == c2)
|
|
continue;
|
|
c1 = tolower(c1);
|
|
c2 = tolower(c2);
|
|
if (c1 != c2)
|
|
break;
|
|
} while (--len);
|
|
return (int)c1 - (int)c2;
|
|
}
|
|
EXPORT_SYMBOL(strncasecmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCASECMP
|
|
int strcasecmp(const char *s1, const char *s2)
|
|
{
|
|
int c1, c2;
|
|
|
|
do {
|
|
c1 = tolower(*s1++);
|
|
c2 = tolower(*s2++);
|
|
} while (c1 == c2 && c1 != 0);
|
|
return c1 - c2;
|
|
}
|
|
EXPORT_SYMBOL(strcasecmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCPY
|
|
/**
|
|
* strcpy - Copy a %NUL terminated string
|
|
* @dest: Where to copy the string to
|
|
* @src: Where to copy the string from
|
|
*/
|
|
#undef strcpy
|
|
char *strcpy(char *dest, const char *src)
|
|
{
|
|
char *tmp = dest;
|
|
|
|
while ((*dest++ = *src++) != '\0')
|
|
/* nothing */;
|
|
return tmp;
|
|
}
|
|
EXPORT_SYMBOL(strcpy);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCPY
|
|
/**
|
|
* strncpy - Copy a length-limited, C-string
|
|
* @dest: Where to copy the string to
|
|
* @src: Where to copy the string from
|
|
* @count: The maximum number of bytes to copy
|
|
*
|
|
* The result is not %NUL-terminated if the source exceeds
|
|
* @count bytes.
|
|
*
|
|
* In the case where the length of @src is less than that of
|
|
* count, the remainder of @dest will be padded with %NUL.
|
|
*
|
|
*/
|
|
char *strncpy(char *dest, const char *src, size_t count)
|
|
{
|
|
char *tmp = dest;
|
|
|
|
while (count) {
|
|
if ((*tmp = *src) != 0)
|
|
src++;
|
|
tmp++;
|
|
count--;
|
|
}
|
|
return dest;
|
|
}
|
|
EXPORT_SYMBOL(strncpy);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRLCPY
|
|
/**
|
|
* strlcpy - Copy a C-string into a sized buffer
|
|
* @dest: Where to copy the string to
|
|
* @src: Where to copy the string from
|
|
* @size: size of destination buffer
|
|
*
|
|
* Compatible with *BSD: the result is always a valid
|
|
* NUL-terminated string that fits in the buffer (unless,
|
|
* of course, the buffer size is zero). It does not pad
|
|
* out the result like strncpy() does.
|
|
*/
|
|
size_t strlcpy(char *dest, const char *src, size_t size)
|
|
{
|
|
size_t ret = strlen(src);
|
|
|
|
if (size) {
|
|
size_t len = (ret >= size) ? size - 1 : ret;
|
|
memcpy(dest, src, len);
|
|
dest[len] = '\0';
|
|
}
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(strlcpy);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSCPY
|
|
/**
|
|
* strscpy - Copy a C-string into a sized buffer
|
|
* @dest: Where to copy the string to
|
|
* @src: Where to copy the string from
|
|
* @count: Size of destination buffer
|
|
*
|
|
* Copy the string, or as much of it as fits, into the dest buffer. The
|
|
* behavior is undefined if the string buffers overlap. The destination
|
|
* buffer is always NUL terminated, unless it's zero-sized.
|
|
*
|
|
* Preferred to strlcpy() since the API doesn't require reading memory
|
|
* from the src string beyond the specified "count" bytes, and since
|
|
* the return value is easier to error-check than strlcpy()'s.
|
|
* In addition, the implementation is robust to the string changing out
|
|
* from underneath it, unlike the current strlcpy() implementation.
|
|
*
|
|
* Preferred to strncpy() since it always returns a valid string, and
|
|
* doesn't unnecessarily force the tail of the destination buffer to be
|
|
* zeroed. If zeroing is desired please use strscpy_pad().
|
|
*
|
|
* Return: The number of characters copied (not including the trailing
|
|
* %NUL) or -E2BIG if the destination buffer wasn't big enough.
|
|
*/
|
|
ssize_t strscpy(char *dest, const char *src, size_t count)
|
|
{
|
|
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
|
|
size_t max = count;
|
|
long res = 0;
|
|
|
|
if (count == 0)
|
|
return -E2BIG;
|
|
|
|
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
|
/*
|
|
* If src is unaligned, don't cross a page boundary,
|
|
* since we don't know if the next page is mapped.
|
|
*/
|
|
if ((long)src & (sizeof(long) - 1)) {
|
|
size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
|
|
if (limit < max)
|
|
max = limit;
|
|
}
|
|
#else
|
|
/* If src or dest is unaligned, don't do word-at-a-time. */
|
|
if (((long) dest | (long) src) & (sizeof(long) - 1))
|
|
max = 0;
|
|
#endif
|
|
|
|
while (max >= sizeof(unsigned long)) {
|
|
unsigned long c, data;
|
|
|
|
c = read_word_at_a_time(src+res);
|
|
if (has_zero(c, &data, &constants)) {
|
|
data = prep_zero_mask(c, data, &constants);
|
|
data = create_zero_mask(data);
|
|
*(unsigned long *)(dest+res) = c & zero_bytemask(data);
|
|
return res + find_zero(data);
|
|
}
|
|
*(unsigned long *)(dest+res) = c;
|
|
res += sizeof(unsigned long);
|
|
count -= sizeof(unsigned long);
|
|
max -= sizeof(unsigned long);
|
|
}
|
|
|
|
while (count) {
|
|
char c;
|
|
|
|
c = src[res];
|
|
dest[res] = c;
|
|
if (!c)
|
|
return res;
|
|
res++;
|
|
count--;
|
|
}
|
|
|
|
/* Hit buffer length without finding a NUL; force NUL-termination. */
|
|
if (res)
|
|
dest[res-1] = '\0';
|
|
|
|
return -E2BIG;
|
|
}
|
|
EXPORT_SYMBOL(strscpy);
|
|
#endif
|
|
|
|
/**
|
|
* stpcpy - copy a string from src to dest returning a pointer to the new end
|
|
* of dest, including src's %NUL-terminator. May overrun dest.
|
|
* @dest: pointer to end of string being copied into. Must be large enough
|
|
* to receive copy.
|
|
* @src: pointer to the beginning of string being copied from. Must not overlap
|
|
* dest.
|
|
*
|
|
* stpcpy differs from strcpy in a key way: the return value is a pointer
|
|
* to the new %NUL-terminating character in @dest. (For strcpy, the return
|
|
* value is a pointer to the start of @dest). This interface is considered
|
|
* unsafe as it doesn't perform bounds checking of the inputs. As such it's
|
|
* not recommended for usage. Instead, its definition is provided in case
|
|
* the compiler lowers other libcalls to stpcpy.
|
|
*/
|
|
char *stpcpy(char *__restrict__ dest, const char *__restrict__ src);
|
|
char *stpcpy(char *__restrict__ dest, const char *__restrict__ src)
|
|
{
|
|
while ((*dest++ = *src++) != '\0')
|
|
/* nothing */;
|
|
return --dest;
|
|
}
|
|
EXPORT_SYMBOL(stpcpy);
|
|
|
|
/**
|
|
* strscpy_pad() - Copy a C-string into a sized buffer
|
|
* @dest: Where to copy the string to
|
|
* @src: Where to copy the string from
|
|
* @count: Size of destination buffer
|
|
*
|
|
* Copy the string, or as much of it as fits, into the dest buffer. The
|
|
* behavior is undefined if the string buffers overlap. The destination
|
|
* buffer is always %NUL terminated, unless it's zero-sized.
|
|
*
|
|
* If the source string is shorter than the destination buffer, zeros
|
|
* the tail of the destination buffer.
|
|
*
|
|
* For full explanation of why you may want to consider using the
|
|
* 'strscpy' functions please see the function docstring for strscpy().
|
|
*
|
|
* Return: The number of characters copied (not including the trailing
|
|
* %NUL) or -E2BIG if the destination buffer wasn't big enough.
|
|
*/
|
|
ssize_t strscpy_pad(char *dest, const char *src, size_t count)
|
|
{
|
|
ssize_t written;
|
|
|
|
written = strscpy(dest, src, count);
|
|
if (written < 0 || written == count - 1)
|
|
return written;
|
|
|
|
memset(dest + written + 1, 0, count - written - 1);
|
|
|
|
return written;
|
|
}
|
|
EXPORT_SYMBOL(strscpy_pad);
|
|
|
|
#ifndef __HAVE_ARCH_STRCAT
|
|
/**
|
|
* strcat - Append one %NUL-terminated string to another
|
|
* @dest: The string to be appended to
|
|
* @src: The string to append to it
|
|
*/
|
|
#undef strcat
|
|
char *strcat(char *dest, const char *src)
|
|
{
|
|
char *tmp = dest;
|
|
|
|
while (*dest)
|
|
dest++;
|
|
while ((*dest++ = *src++) != '\0')
|
|
;
|
|
return tmp;
|
|
}
|
|
EXPORT_SYMBOL(strcat);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCAT
|
|
/**
|
|
* strncat - Append a length-limited, C-string to another
|
|
* @dest: The string to be appended to
|
|
* @src: The string to append to it
|
|
* @count: The maximum numbers of bytes to copy
|
|
*
|
|
* Note that in contrast to strncpy(), strncat() ensures the result is
|
|
* terminated.
|
|
*/
|
|
char *strncat(char *dest, const char *src, size_t count)
|
|
{
|
|
char *tmp = dest;
|
|
|
|
if (count) {
|
|
while (*dest)
|
|
dest++;
|
|
while ((*dest++ = *src++) != 0) {
|
|
if (--count == 0) {
|
|
*dest = '\0';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return tmp;
|
|
}
|
|
EXPORT_SYMBOL(strncat);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRLCAT
|
|
/**
|
|
* strlcat - Append a length-limited, C-string to another
|
|
* @dest: The string to be appended to
|
|
* @src: The string to append to it
|
|
* @count: The size of the destination buffer.
|
|
*/
|
|
size_t strlcat(char *dest, const char *src, size_t count)
|
|
{
|
|
size_t dsize = strlen(dest);
|
|
size_t len = strlen(src);
|
|
size_t res = dsize + len;
|
|
|
|
/* This would be a bug */
|
|
BUG_ON(dsize >= count);
|
|
|
|
dest += dsize;
|
|
count -= dsize;
|
|
if (len >= count)
|
|
len = count-1;
|
|
memcpy(dest, src, len);
|
|
dest[len] = 0;
|
|
return res;
|
|
}
|
|
EXPORT_SYMBOL(strlcat);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCMP
|
|
/**
|
|
* strcmp - Compare two strings
|
|
* @cs: One string
|
|
* @ct: Another string
|
|
*/
|
|
#undef strcmp
|
|
int strcmp(const char *cs, const char *ct)
|
|
{
|
|
unsigned char c1, c2;
|
|
|
|
while (1) {
|
|
c1 = *cs++;
|
|
c2 = *ct++;
|
|
if (c1 != c2)
|
|
return c1 < c2 ? -1 : 1;
|
|
if (!c1)
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(strcmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCMP
|
|
/**
|
|
* strncmp - Compare two length-limited strings
|
|
* @cs: One string
|
|
* @ct: Another string
|
|
* @count: The maximum number of bytes to compare
|
|
*/
|
|
int strncmp(const char *cs, const char *ct, size_t count)
|
|
{
|
|
unsigned char c1, c2;
|
|
|
|
while (count) {
|
|
c1 = *cs++;
|
|
c2 = *ct++;
|
|
if (c1 != c2)
|
|
return c1 < c2 ? -1 : 1;
|
|
if (!c1)
|
|
break;
|
|
count--;
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(strncmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCHR
|
|
/**
|
|
* strchr - Find the first occurrence of a character in a string
|
|
* @s: The string to be searched
|
|
* @c: The character to search for
|
|
*/
|
|
char *strchr(const char *s, int c)
|
|
{
|
|
for (; *s != (char)c; ++s)
|
|
if (*s == '\0')
|
|
return NULL;
|
|
return (char *)s;
|
|
}
|
|
EXPORT_SYMBOL(strchr);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCHRNUL
|
|
/**
|
|
* strchrnul - Find and return a character in a string, or end of string
|
|
* @s: The string to be searched
|
|
* @c: The character to search for
|
|
*
|
|
* Returns pointer to first occurrence of 'c' in s. If c is not found, then
|
|
* return a pointer to the null byte at the end of s.
|
|
*/
|
|
char *strchrnul(const char *s, int c)
|
|
{
|
|
while (*s && *s != (char)c)
|
|
s++;
|
|
return (char *)s;
|
|
}
|
|
EXPORT_SYMBOL(strchrnul);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRRCHR
|
|
/**
|
|
* strrchr - Find the last occurrence of a character in a string
|
|
* @s: The string to be searched
|
|
* @c: The character to search for
|
|
*/
|
|
char *strrchr(const char *s, int c)
|
|
{
|
|
const char *last = NULL;
|
|
do {
|
|
if (*s == (char)c)
|
|
last = s;
|
|
} while (*s++);
|
|
return (char *)last;
|
|
}
|
|
EXPORT_SYMBOL(strrchr);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNCHR
|
|
/**
|
|
* strnchr - Find a character in a length limited string
|
|
* @s: The string to be searched
|
|
* @count: The number of characters to be searched
|
|
* @c: The character to search for
|
|
*/
|
|
char *strnchr(const char *s, size_t count, int c)
|
|
{
|
|
for (; count-- && *s != '\0'; ++s)
|
|
if (*s == (char)c)
|
|
return (char *)s;
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(strnchr);
|
|
#endif
|
|
|
|
/**
|
|
* skip_spaces - Removes leading whitespace from @str.
|
|
* @str: The string to be stripped.
|
|
*
|
|
* Returns a pointer to the first non-whitespace character in @str.
|
|
*/
|
|
char *skip_spaces(const char *str)
|
|
{
|
|
while (isspace(*str))
|
|
++str;
|
|
return (char *)str;
|
|
}
|
|
EXPORT_SYMBOL(skip_spaces);
|
|
|
|
/**
|
|
* strim - Removes leading and trailing whitespace from @s.
|
|
* @s: The string to be stripped.
|
|
*
|
|
* Note that the first trailing whitespace is replaced with a %NUL-terminator
|
|
* in the given string @s. Returns a pointer to the first non-whitespace
|
|
* character in @s.
|
|
*/
|
|
char *strim(char *s)
|
|
{
|
|
size_t size;
|
|
char *end;
|
|
|
|
size = strlen(s);
|
|
if (!size)
|
|
return s;
|
|
|
|
end = s + size - 1;
|
|
while (end >= s && isspace(*end))
|
|
end--;
|
|
*(end + 1) = '\0';
|
|
|
|
return skip_spaces(s);
|
|
}
|
|
EXPORT_SYMBOL(strim);
|
|
|
|
#ifndef __HAVE_ARCH_STRLEN
|
|
/**
|
|
* strlen - Find the length of a string
|
|
* @s: The string to be sized
|
|
*/
|
|
size_t strlen(const char *s)
|
|
{
|
|
const char *sc;
|
|
|
|
for (sc = s; *sc != '\0'; ++sc)
|
|
/* nothing */;
|
|
return sc - s;
|
|
}
|
|
EXPORT_SYMBOL(strlen);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNLEN
|
|
/**
|
|
* strnlen - Find the length of a length-limited string
|
|
* @s: The string to be sized
|
|
* @count: The maximum number of bytes to search
|
|
*/
|
|
size_t strnlen(const char *s, size_t count)
|
|
{
|
|
const char *sc;
|
|
|
|
for (sc = s; count-- && *sc != '\0'; ++sc)
|
|
/* nothing */;
|
|
return sc - s;
|
|
}
|
|
EXPORT_SYMBOL(strnlen);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSPN
|
|
/**
|
|
* strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
|
|
* @s: The string to be searched
|
|
* @accept: The string to search for
|
|
*/
|
|
size_t strspn(const char *s, const char *accept)
|
|
{
|
|
const char *p;
|
|
const char *a;
|
|
size_t count = 0;
|
|
|
|
for (p = s; *p != '\0'; ++p) {
|
|
for (a = accept; *a != '\0'; ++a) {
|
|
if (*p == *a)
|
|
break;
|
|
}
|
|
if (*a == '\0')
|
|
return count;
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
EXPORT_SYMBOL(strspn);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRCSPN
|
|
/**
|
|
* strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
|
|
* @s: The string to be searched
|
|
* @reject: The string to avoid
|
|
*/
|
|
size_t strcspn(const char *s, const char *reject)
|
|
{
|
|
const char *p;
|
|
const char *r;
|
|
size_t count = 0;
|
|
|
|
for (p = s; *p != '\0'; ++p) {
|
|
for (r = reject; *r != '\0'; ++r) {
|
|
if (*p == *r)
|
|
return count;
|
|
}
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
EXPORT_SYMBOL(strcspn);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRPBRK
|
|
/**
|
|
* strpbrk - Find the first occurrence of a set of characters
|
|
* @cs: The string to be searched
|
|
* @ct: The characters to search for
|
|
*/
|
|
char *strpbrk(const char *cs, const char *ct)
|
|
{
|
|
const char *sc1, *sc2;
|
|
|
|
for (sc1 = cs; *sc1 != '\0'; ++sc1) {
|
|
for (sc2 = ct; *sc2 != '\0'; ++sc2) {
|
|
if (*sc1 == *sc2)
|
|
return (char *)sc1;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(strpbrk);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSEP
|
|
/**
|
|
* strsep - Split a string into tokens
|
|
* @s: The string to be searched
|
|
* @ct: The characters to search for
|
|
*
|
|
* strsep() updates @s to point after the token, ready for the next call.
|
|
*
|
|
* It returns empty tokens, too, behaving exactly like the libc function
|
|
* of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
|
|
* Same semantics, slimmer shape. ;)
|
|
*/
|
|
char *strsep(char **s, const char *ct)
|
|
{
|
|
char *sbegin = *s;
|
|
char *end;
|
|
|
|
if (sbegin == NULL)
|
|
return NULL;
|
|
|
|
end = strpbrk(sbegin, ct);
|
|
if (end)
|
|
*end++ = '\0';
|
|
*s = end;
|
|
return sbegin;
|
|
}
|
|
EXPORT_SYMBOL(strsep);
|
|
#endif
|
|
|
|
/**
|
|
* sysfs_streq - return true if strings are equal, modulo trailing newline
|
|
* @s1: one string
|
|
* @s2: another string
|
|
*
|
|
* This routine returns true iff two strings are equal, treating both
|
|
* NUL and newline-then-NUL as equivalent string terminations. It's
|
|
* geared for use with sysfs input strings, which generally terminate
|
|
* with newlines but are compared against values without newlines.
|
|
*/
|
|
bool sysfs_streq(const char *s1, const char *s2)
|
|
{
|
|
while (*s1 && *s1 == *s2) {
|
|
s1++;
|
|
s2++;
|
|
}
|
|
|
|
if (*s1 == *s2)
|
|
return true;
|
|
if (!*s1 && *s2 == '\n' && !s2[1])
|
|
return true;
|
|
if (*s1 == '\n' && !s1[1] && !*s2)
|
|
return true;
|
|
return false;
|
|
}
|
|
EXPORT_SYMBOL(sysfs_streq);
|
|
|
|
/**
|
|
* match_string - matches given string in an array
|
|
* @array: array of strings
|
|
* @n: number of strings in the array or -1 for NULL terminated arrays
|
|
* @string: string to match with
|
|
*
|
|
* Return:
|
|
* index of a @string in the @array if matches, or %-EINVAL otherwise.
|
|
*/
|
|
int match_string(const char * const *array, size_t n, const char *string)
|
|
{
|
|
int index;
|
|
const char *item;
|
|
|
|
for (index = 0; index < n; index++) {
|
|
item = array[index];
|
|
if (!item)
|
|
break;
|
|
if (!strcmp(item, string))
|
|
return index;
|
|
}
|
|
|
|
return -EINVAL;
|
|
}
|
|
EXPORT_SYMBOL(match_string);
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET
|
|
/**
|
|
* memset - Fill a region of memory with the given value
|
|
* @s: Pointer to the start of the area.
|
|
* @c: The byte to fill the area with
|
|
* @count: The size of the area.
|
|
*
|
|
* Do not use memset() to access IO space, use memset_io() instead.
|
|
*/
|
|
void *memset(void *s, int c, size_t count)
|
|
{
|
|
char *xs = s;
|
|
|
|
while (count--)
|
|
*xs++ = c;
|
|
return s;
|
|
}
|
|
EXPORT_SYMBOL(memset);
|
|
#endif
|
|
|
|
/**
|
|
* memzero_explicit - Fill a region of memory (e.g. sensitive
|
|
* keying data) with 0s.
|
|
* @s: Pointer to the start of the area.
|
|
* @count: The size of the area.
|
|
*
|
|
* Note: usually using memset() is just fine (!), but in cases
|
|
* where clearing out _local_ data at the end of a scope is
|
|
* necessary, memzero_explicit() should be used instead in
|
|
* order to prevent the compiler from optimising away zeroing.
|
|
*
|
|
* memzero_explicit() doesn't need an arch-specific version as
|
|
* it just invokes the one of memset() implicitly.
|
|
*/
|
|
void memzero_explicit(void *s, size_t count)
|
|
{
|
|
memset(s, 0, count);
|
|
barrier_data(s);
|
|
}
|
|
EXPORT_SYMBOL(memzero_explicit);
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET16
|
|
/**
|
|
* memset16() - Fill a memory area with a uint16_t
|
|
* @s: Pointer to the start of the area.
|
|
* @v: The value to fill the area with
|
|
* @count: The number of values to store
|
|
*
|
|
* Differs from memset() in that it fills with a uint16_t instead
|
|
* of a byte. Remember that @count is the number of uint16_ts to
|
|
* store, not the number of bytes.
|
|
*/
|
|
void *memset16(uint16_t *s, uint16_t v, size_t count)
|
|
{
|
|
uint16_t *xs = s;
|
|
|
|
while (count--)
|
|
*xs++ = v;
|
|
return s;
|
|
}
|
|
EXPORT_SYMBOL(memset16);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET32
|
|
/**
|
|
* memset32() - Fill a memory area with a uint32_t
|
|
* @s: Pointer to the start of the area.
|
|
* @v: The value to fill the area with
|
|
* @count: The number of values to store
|
|
*
|
|
* Differs from memset() in that it fills with a uint32_t instead
|
|
* of a byte. Remember that @count is the number of uint32_ts to
|
|
* store, not the number of bytes.
|
|
*/
|
|
void *memset32(uint32_t *s, uint32_t v, size_t count)
|
|
{
|
|
uint32_t *xs = s;
|
|
|
|
while (count--)
|
|
*xs++ = v;
|
|
return s;
|
|
}
|
|
EXPORT_SYMBOL(memset32);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET64
|
|
/**
|
|
* memset64() - Fill a memory area with a uint64_t
|
|
* @s: Pointer to the start of the area.
|
|
* @v: The value to fill the area with
|
|
* @count: The number of values to store
|
|
*
|
|
* Differs from memset() in that it fills with a uint64_t instead
|
|
* of a byte. Remember that @count is the number of uint64_ts to
|
|
* store, not the number of bytes.
|
|
*/
|
|
void *memset64(uint64_t *s, uint64_t v, size_t count)
|
|
{
|
|
uint64_t *xs = s;
|
|
|
|
while (count--)
|
|
*xs++ = v;
|
|
return s;
|
|
}
|
|
EXPORT_SYMBOL(memset64);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCPY
|
|
/**
|
|
* memcpy - Copy one area of memory to another
|
|
* @dest: Where to copy to
|
|
* @src: Where to copy from
|
|
* @count: The size of the area.
|
|
*
|
|
* You should not use this function to access IO space, use memcpy_toio()
|
|
* or memcpy_fromio() instead.
|
|
*/
|
|
void *memcpy(void *dest, const void *src, size_t count)
|
|
{
|
|
char *tmp = dest;
|
|
const char *s = src;
|
|
|
|
while (count--)
|
|
*tmp++ = *s++;
|
|
return dest;
|
|
}
|
|
EXPORT_SYMBOL(memcpy);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMMOVE
|
|
/**
|
|
* memmove - Copy one area of memory to another
|
|
* @dest: Where to copy to
|
|
* @src: Where to copy from
|
|
* @count: The size of the area.
|
|
*
|
|
* Unlike memcpy(), memmove() copes with overlapping areas.
|
|
*/
|
|
void *memmove(void *dest, const void *src, size_t count)
|
|
{
|
|
char *tmp;
|
|
const char *s;
|
|
|
|
if (dest <= src) {
|
|
tmp = dest;
|
|
s = src;
|
|
while (count--)
|
|
*tmp++ = *s++;
|
|
} else {
|
|
tmp = dest;
|
|
tmp += count;
|
|
s = src;
|
|
s += count;
|
|
while (count--)
|
|
*--tmp = *--s;
|
|
}
|
|
return dest;
|
|
}
|
|
EXPORT_SYMBOL(memmove);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCMP
|
|
/**
|
|
* memcmp - Compare two areas of memory
|
|
* @cs: One area of memory
|
|
* @ct: Another area of memory
|
|
* @count: The size of the area.
|
|
*/
|
|
#undef memcmp
|
|
__visible int memcmp(const void *cs, const void *ct, size_t count)
|
|
{
|
|
const unsigned char *su1, *su2;
|
|
int res = 0;
|
|
|
|
for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
|
|
if ((res = *su1 - *su2) != 0)
|
|
break;
|
|
return res;
|
|
}
|
|
EXPORT_SYMBOL(memcmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_BCMP
|
|
/**
|
|
* bcmp - returns 0 if and only if the buffers have identical contents.
|
|
* @a: pointer to first buffer.
|
|
* @b: pointer to second buffer.
|
|
* @len: size of buffers.
|
|
*
|
|
* The sign or magnitude of a non-zero return value has no particular
|
|
* meaning, and architectures may implement their own more efficient bcmp(). So
|
|
* while this particular implementation is a simple (tail) call to memcmp, do
|
|
* not rely on anything but whether the return value is zero or non-zero.
|
|
*/
|
|
#undef bcmp
|
|
int bcmp(const void *a, const void *b, size_t len)
|
|
{
|
|
return memcmp(a, b, len);
|
|
}
|
|
EXPORT_SYMBOL(bcmp);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMSCAN
|
|
/**
|
|
* memscan - Find a character in an area of memory.
|
|
* @addr: The memory area
|
|
* @c: The byte to search for
|
|
* @size: The size of the area.
|
|
*
|
|
* returns the address of the first occurrence of @c, or 1 byte past
|
|
* the area if @c is not found
|
|
*/
|
|
void *memscan(void *addr, int c, size_t size)
|
|
{
|
|
unsigned char *p = addr;
|
|
|
|
while (size) {
|
|
if (*p == c)
|
|
return (void *)p;
|
|
p++;
|
|
size--;
|
|
}
|
|
return (void *)p;
|
|
}
|
|
EXPORT_SYMBOL(memscan);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRSTR
|
|
/**
|
|
* strstr - Find the first substring in a %NUL terminated string
|
|
* @s1: The string to be searched
|
|
* @s2: The string to search for
|
|
*/
|
|
char *strstr(const char *s1, const char *s2)
|
|
{
|
|
size_t l1, l2;
|
|
|
|
l2 = strlen(s2);
|
|
if (!l2)
|
|
return (char *)s1;
|
|
l1 = strlen(s1);
|
|
while (l1 >= l2) {
|
|
l1--;
|
|
if (!memcmp(s1, s2, l2))
|
|
return (char *)s1;
|
|
s1++;
|
|
}
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(strstr);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_STRNSTR
|
|
/**
|
|
* strnstr - Find the first substring in a length-limited string
|
|
* @s1: The string to be searched
|
|
* @s2: The string to search for
|
|
* @len: the maximum number of characters to search
|
|
*/
|
|
char *strnstr(const char *s1, const char *s2, size_t len)
|
|
{
|
|
size_t l2;
|
|
|
|
l2 = strlen(s2);
|
|
if (!l2)
|
|
return (char *)s1;
|
|
while (len >= l2) {
|
|
len--;
|
|
if (!memcmp(s1, s2, l2))
|
|
return (char *)s1;
|
|
s1++;
|
|
}
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(strnstr);
|
|
#endif
|
|
|
|
#ifndef __HAVE_ARCH_MEMCHR
|
|
/**
|
|
* memchr - Find a character in an area of memory.
|
|
* @s: The memory area
|
|
* @c: The byte to search for
|
|
* @n: The size of the area.
|
|
*
|
|
* returns the address of the first occurrence of @c, or %NULL
|
|
* if @c is not found
|
|
*/
|
|
void *memchr(const void *s, int c, size_t n)
|
|
{
|
|
const unsigned char *p = s;
|
|
while (n-- != 0) {
|
|
if ((unsigned char)c == *p++) {
|
|
return (void *)(p - 1);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(memchr);
|
|
#endif
|
|
|
|
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
|
|
{
|
|
while (bytes) {
|
|
if (*start != value)
|
|
return (void *)start;
|
|
start++;
|
|
bytes--;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* memchr_inv - Find an unmatching character in an area of memory.
|
|
* @start: The memory area
|
|
* @c: Find a character other than c
|
|
* @bytes: The size of the area.
|
|
*
|
|
* returns the address of the first character other than @c, or %NULL
|
|
* if the whole buffer contains just @c.
|
|
*/
|
|
void *memchr_inv(const void *start, int c, size_t bytes)
|
|
{
|
|
u8 value = c;
|
|
u64 value64;
|
|
unsigned int words, prefix;
|
|
|
|
if (bytes <= 16)
|
|
return check_bytes8(start, value, bytes);
|
|
|
|
value64 = value;
|
|
#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
|
|
value64 *= 0x0101010101010101ULL;
|
|
#elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER)
|
|
value64 *= 0x01010101;
|
|
value64 |= value64 << 32;
|
|
#else
|
|
value64 |= value64 << 8;
|
|
value64 |= value64 << 16;
|
|
value64 |= value64 << 32;
|
|
#endif
|
|
|
|
prefix = (unsigned long)start % 8;
|
|
if (prefix) {
|
|
u8 *r;
|
|
|
|
prefix = 8 - prefix;
|
|
r = check_bytes8(start, value, prefix);
|
|
if (r)
|
|
return r;
|
|
start += prefix;
|
|
bytes -= prefix;
|
|
}
|
|
|
|
words = bytes / 8;
|
|
|
|
while (words) {
|
|
if (*(u64 *)start != value64)
|
|
return check_bytes8(start, value, 8);
|
|
start += 8;
|
|
words--;
|
|
}
|
|
|
|
return check_bytes8(start, value, bytes % 8);
|
|
}
|
|
EXPORT_SYMBOL(memchr_inv);
|
|
|
|
/**
|
|
* strreplace - Replace all occurrences of character in string.
|
|
* @s: The string to operate on.
|
|
* @old: The character being replaced.
|
|
* @new: The character @old is replaced with.
|
|
*
|
|
* Returns pointer to the nul byte at the end of @s.
|
|
*/
|
|
char *strreplace(char *s, char old, char new)
|
|
{
|
|
for (; *s; ++s)
|
|
if (*s == old)
|
|
*s = new;
|
|
return s;
|
|
}
|
|
EXPORT_SYMBOL(strreplace);
|
|
|
|
void fortify_panic(const char *name)
|
|
{
|
|
pr_emerg("detected buffer overflow in %s\n", name);
|
|
BUG();
|
|
}
|
|
EXPORT_SYMBOL(fortify_panic);
|