mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmJfsXYACgkQONu9yGCS aT4FSg/+JNuh/FNAa4Es7pC4O3BpsaIIji6MEYjSw1sMMgqtmXCnbm+1TCsgCOee auBiVGZzNjLRNESrqOPisEA5aUs31i3fVOD0c55bHgOhqxtLxaU7HmtqIlfvnEKu a49LRtqq3AEObilBFeBHQnUrTEGO/MnI4XoUsLdR6FWJBnYsBLczDdNGYIWZ/hCX y129piS/P53nHfmPTMH0De6soOXFIx3d82437pwA0vDEANtMx8lyaW+kdPSsgZl7 03JAQFW1KRjiLzHt+9w7c78dbnyEIQd78W4wn4NFglN7Ybxi7NFEjaf0xnyerwG2 b38ofe8Gw5IqUzF6eCHliG1UgQwZD7pNBjOIKukrpxL3bIEcTOhIQeu1HCm901k0 /Y53ju6tNCrv2PbHVylYibasxPiA2gxzFwJW/JvWWTtZZ6AwkZV0fs3LXXpmDix3 7n/QBjQcz4sOAAWwFoaxneUOTaNoFseZtW/dgqbq+Ukgt2SCP15EUDMVjIXi3fDr 3z5+QvO5IbjbcsFShVfDQ6RfnALp4TWXbrPQ+RTK77BZTbMNg7wjKxBC2MmTmStI 8aiDYecKR4FOXdW930zxYHS76gx57V30hur7jlqjFz0uNYnXU/R42kKUxEqD/86G UNX+zMv9uH5INANIy4P6DNZyZoTHQgdMIuuhKvntg/G3BcQ5I7k= =zpoO -----END PGP SIGNATURE----- Merge 4.14.276 into android-4.14-stable Changes in 4.14.276 USB: serial: pl2303: add IBM device IDs USB: serial: simple: add Nokia phone driver netdevice: add the case if dev is NULL virtio_console: break out of buf poll on remove ethernet: sun: Free the coherent when failing in probing spi: Fix invalid sgs value spi: Fix erroneous sgs value with min_t() af_key: add __GFP_ZERO flag for compose_sadb_supported in function pfkey_register fuse: fix pipe buffer lifetime for direct_io tpm: fix reference counting for struct tpm_chip block: Add a helper to validate the block size virtio-blk: Use blk_validate_block_size() to validate block size USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c coresight: Fix TRCCONFIGR.QE sysfs interface iio: inkern: apply consumer scale on IIO_VAL_INT cases iio: inkern: apply consumer scale when no channel scale is available iio: inkern: make a best effort on offset calculation clk: uniphier: Fix fixed-rate initialization ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE Documentation: add link to stable release candidate tree Documentation: update stable tree link SUNRPC: avoid race between mod_timer() and del_timer_sync() NFSD: prevent underflow in nfssvc_decode_writeargs() pinctrl: samsung: drop pin banks references on error paths can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path jffs2: fix use-after-free in jffs2_clear_xattr_subsystem jffs2: fix memory leak in jffs2_do_mount_fs jffs2: fix memory leak in jffs2_scan_medium mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node mempolicy: mbind_range() set_policy() after vma_merge() scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands qed: display VF trust config qed: validate and restrict untrusted VFs vlan promisc mode Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads" ALSA: cs4236: fix an incorrect NULL check on list iterator drbd: fix potential silent data corruption ACPI: properties: Consistently return -ENOENT if there are no more references drivers: hamradio: 6pack: fix UAF bug caused by mod_timer() video: fbdev: sm712fb: Fix crash in smtcfb_read() video: fbdev: atari: Atari 2 bpp (STe) palette bugfix ARM: dts: at91: sama5d2: Fix PMERRLOC resource size ARM: dts: exynos: fix UART3 pins configuration in Exynos5250 ARM: dts: exynos: add missing HDMI supplies on SMDK5250 ARM: dts: exynos: add missing HDMI supplies on SMDK5420 carl9170: fix missing bit-wise or operator for tx_params thermal: int340x: Increase bitmap size lib/raid6/test: fix multiple definition linking error DEC: Limit PMAX memory probing to R3k systems media: davinci: vpif: fix unbalanced runtime PM get brcmfmac: firmware: Allocate space for default boardrev in nvram brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio PCI: pciehp: Clear cmd_busy bit in polling mode crypto: authenc - Fix sleep in atomic context in decrypt_tail crypto: mxs-dcp - Fix scatterlist processing spi: tegra114: Add missing IRQ check in tegra_spi_probe selftests/x86: Add validity check and allow field splitting spi: pxa2xx-pci: Balance reference count for PCI DMA device hwmon: (pmbus) Add mutex to regulator ops hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING PM: hibernate: fix __setup handler error handling PM: suspend: fix return value of __setup handler hwrng: atmel - disable trng on failure path crypto: vmx - add missing dependencies ACPI: APEI: fix return value of __setup handlers crypto: ccp - ccp_dmaengine_unregister release dma channels hwmon: (pmbus) Add Vin unit off handling clocksource: acpi_pm: fix return value of __setup handler sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa perf/core: Fix address filter parser for multiple filters perf/x86/intel/pt: Fix address filter config for 32-bit kernel media: coda: Fix missing put_device() call in coda_get_vdoa_data video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe() video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name() ARM: dts: qcom: ipq4019: fix sleep clock soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe media: usb: go7007: s2250-board: fix leak in probe() ASoC: ti: davinci-i2s: Add check for clk_enable() ALSA: spi: Add check for clk_enable() arm64: dts: ns2: Fix spi-cpol and spi-cpha property arm64: dts: broadcom: Fix sata nodename printk: fix return value of printk.devkmsg __setup handler ASoC: mxs-saif: Handle errors for clk_enable ASoC: atmel_ssc_dai: Handle errors for clk_enable memory: emif: Add check for setup_interrupts memory: emif: check the pointer temp in get_device_details() ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction media: stk1160: If start stream fails, return buffers with VB2_BUF_STATE_QUEUED ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe ASoC: wm8350: Handle error for wm8350_register_irq ASoC: fsi: Add check for clk_enable video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of ASoC: dmaengine: do not use a NULL prepare_slave_config() callback ASoC: mxs: Fix error handling in mxs_sgtl5000_probe ASoC: imx-es8328: Fix error return code in imx_es8328_probe() ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in msm8916_wcd_digital_probe mtd: onenand: Check for error irq drm/edid: Don't clear formats if using deep color ath9k_htc: fix uninit value bugs power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe ray_cs: Check ioremap return value power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports iwlwifi: Fix -EIO error code that is never returned dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS scsi: pm8001: Fix command initialization in pm80XX_send_read_log() scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() scsi: pm8001: Fix abort all task initialization TOMOYO: fix __setup handlers return values ext2: correct max file size computing drm/tegra: Fix reference leak in tegra_dsi_ganged_probe power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false return KVM: x86: Fix emulation in writing cr8 KVM: x86/emulator: Defer not-present segment check in __load_segment_descriptor() i2c: xiic: Make bus names unique power: supply: wm8350-power: Handle error for wm8350_register_irq power: supply: wm8350-power: Add missing free in free_charger_irq PCI: Reduce warnings on possible RW1C corruption powerpc/sysdev: fix incorrect use to determine if list is empty mfd: mc13xxx: Add check for mc13xxx_irq_request vxcan: enable local echo for sent CAN frames MIPS: RB532: fix return value of __setup handler mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init USB: storage: ums-realtek: fix error code in rts51x_read_mem() af_netlink: Fix shift out of bounds in group mask calculation i2c: mux: demux-pinctrl: do not deactivate a master that is not active tcp: ensure PMTU updates are processed during fastopen mfd: asic3: Add missing iounmap() on error asic3_mfd_probe mxser: fix xmit_buf leak in activate when LSR == 0xff pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add() staging:iio:adc:ad7280a: Fix handing of device address bit reversing. serial: 8250_mid: Balance reference count for PCI DMA device serial: 8250: Fix race condition in RTS-after-send handling iio: adc: Add check for devm_request_threaded_irq clk: qcom: clk-rcg2: Update the frac table for pixel clock remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region clk: loongson1: Terminate clk_div_table with sentinel element clk: clps711x: Terminate clk_div_table with sentinel element clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver NFS: remove unneeded check in decode_devicenotify_args() pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe tty: hvc: fix return value of __setup handler kgdboc: fix return value of __setup handler kgdbts: fix return value of __setup handler jfs: fix divide error in dbNextAG netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options xen: fix is_xen_pmu() net: phy: broadcom: Fix brcm_fet_config_init() qlcnic: dcb: default to returning -EOPNOTSUPP net/x25: Fix null-ptr-deref caused by x25_disconnect NFSv4/pNFS: Fix another issue with a list iterator pointing to the head lib/test: use after free in register_test_dev_kmod() selinux: use correct type for context length loop: use sysfs_emit() in the sysfs xxx show() Fix incorrect type in assignment of ipv6 port for audit irqchip/nvic: Release nvic_base upon failure ACPICA: Avoid walking the ACPI Namespace if it is not there ACPI/APEI: Limit printable size of BERT table data PM: core: keep irq flags in device_pm_check_callbacks() spi: tegra20: Use of_device_get_match_data() ext4: don't BUG if someone dirty pages without asking ext4 first ntfs: add sanity check on allocation size video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow video: fbdev: w100fb: Reset global state video: fbdev: cirrusfb: check pixclock to avoid divide by zero video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960 ARM: dts: bcm2837: Add the missing L1/L2 cache information video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf() video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of snprintf() ASoC: soc-core: skip zero num_dai component in searching dai name media: cx88-mpeg: clear interrupt status register before streaming video ARM: tegra: tamonten: Fix I2C3 pad setting ARM: mmp: Fix failure to remove sram device video: fbdev: sm712fb: Fix crash in smtcfb_write() media: hdpvr: initialize dev->worker at hdpvr_register_videodev mmc: host: Return an error when ->enable_sdio_irq() ops is missing powerpc/lib/sstep: Fix 'sthcx' instruction powerpc/lib/sstep: Fix build errors with newer binutils scsi: qla2xxx: Fix warning for missing error code scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair() KVM: Prevent module exit until all VMs are freed ubifs: rename_whiteout: Fix double free for whiteout_ui->data ubifs: Add missing iput if do_tmpfile() failed in rename whiteout ubifs: setflags: Make dirtied_ino_d 8 bytes aligned ubifs: rename_whiteout: correct old_dir size computing can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path can: mcba_usb: properly check endpoint type gfs2: Make sure FITRIM minlen is rounded up to fs block size pinctrl: pinconf-generic: Print arguments for bias-pull-* ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl ACPI: CPPC: Avoid out of bounds access when parsing _CPC data mm/mmap: return 1 from stack_guard_gap __setup() handler mm/memcontrol: return 1 from cgroup.memory __setup() handler ubi: fastmap: Return error code if memory allocation fails in add_aeb() ASoC: topology: Allow TLV control to be either read or write ARM: dts: spear1340: Update serial node properties ARM: dts: spear13xx: Update SPI dma properties openvswitch: Fixed nd target mask field in the flow dump. KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated ubifs: Rectify space amount budget for mkdir/tmpfile operations rtc: wm8350: Handle error for wm8350_register_irq ARM: 9187/1: JIVE: fix return value of __setup handler KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111 ptp: replace snprintf with sysfs_emit powerpc: dts: t104xrdb: fix phy type for FMAN 4/5 scsi: mvsas: Replace snprintf() with sysfs_emit() scsi: bfa: Replace snprintf() with sysfs_emit() power: supply: axp20x_battery: properly report current when discharging powerpc: Set crashkernel offset to mid of RMA region PCI: aardvark: Fix support for MSI interrupts iommu/arm-smmu-v3: fix event handling soft lockup dm ioctl: prevent potential spectre v1 gadget scsi: pm8001: Fix pm8001_mpi_task_abort_resp() scsi: aha152x: Fix aha152x_setup() __setup handler return value net/smc: correct settings of RMB window update limit macvtap: advertise link netns via netlink bnxt_en: Eliminate unintended link toggle during FW reset MIPS: fix fortify panic when copying asm exception handlers scsi: libfc: Fix use after free in fc_exch_abts_resp() usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm xtensa: fix DTC warning unit_address_format Bluetooth: Fix use after free in hci_send_acl init/main.c: return 1 from handled __setup() functions w1: w1_therm: fixes w1_seq for ds28ea00 sensors SUNRPC/call_alloc: async tasks mustn't block waiting for memory NFS: swap IO handling is slightly different for O_DIRECT IO NFS: swap-out must always use STABLE writes. serial: samsung_tty: do not unlock port->lock for uart_write_wakeup() virtio_console: eliminate anonymous module_init & module_exit jfs: prevent NULL deref in diFree parisc: Fix CPU affinity for Lasi, WAX and Dino chips ipv6: add missing tx timestamping on IPPROTO_RAW net: add missing SOF_TIMESTAMPING_OPT_ID support mm: fix race between MADV_FREE reclaim and blkdev direct IO read drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire() scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one() net: stmmac: Fix unset max_speed difference between DT and non-DT platforms drm/imx: Fix memory leak in imx_pd_connector_get_modes drbd: Fix five use after free bugs in get_initial_state Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning" mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0) mm/mempolicy: fix mpol_new leak in shared_policy_replace x86/pm: Save the MSR validity status at context setup x86/speculation: Restore speculation related MSRs during S3 resume btrfs: fix qgroup reserve overflow the qgroup limit arm64: patch_text: Fixup last cpu should be master perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error" mm: don't skip swap entry even if zap_details specified arm64: module: remove (NOLOAD) from linker script mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning cgroup: Use open-time credentials for process migraton perm checks cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv cgroup: Use open-time cgroup namespace for process migration perm checks xfrm: policy: match with both mark and mask on user interfaces memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe veth: Ensure eth header is in skb's linear part gpiolib: acpi: use correct format characters mlxsw: i2c: Fix initialization error flow net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link nfc: nci: add flush_workqueue to prevent uaf cifs: potential buffer overflow in handling symlinks drm/amd: Add USBC connector ID drm/amdkfd: Check for potential null return of kmalloc_array() Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer scsi: target: tcmu: Fix possible page UAF scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024 net: micrel: fix KS8851_MLL Kconfig ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs gpu: ipu-v3: Fix dev_dbg frequency output scsi: mvsas: Add PCI ID of RocketRaid 2640 drivers: net: slip: fix NPD bug in sl_tx_timeout() mm, page_alloc: fix build_zonerefs_node() mm: kmemleak: take a full lowmem check in kmemleak_*_phys() gcc-plugins: latent_entropy: use /dev/urandom ALSA: pcm: Test for "silence" field in struct "pcm_format_data" ARM: davinci: da850-evm: Avoid NULL pointer dereference smp: Fix offline cpu check in flush_smp_call_function_queue() i2c: pasemi: Wait for write xfers to finish Linux 4.14.276 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I45d8292ce654c0236758030a89b4618cf3a3d87b
476 lines
11 KiB
C
476 lines
11 KiB
C
/*
|
|
* NSA Security-Enhanced Linux (SELinux) security module
|
|
*
|
|
* This file contains the SELinux XFRM hook function implementations.
|
|
*
|
|
* Authors: Serge Hallyn <sergeh@us.ibm.com>
|
|
* Trent Jaeger <jaegert@us.ibm.com>
|
|
*
|
|
* Updated: Venkat Yekkirala <vyekkirala@TrustedCS.com>
|
|
*
|
|
* Granular IPSec Associations for use in MLS environments.
|
|
*
|
|
* Copyright (C) 2005 International Business Machines Corporation
|
|
* Copyright (C) 2006 Trusted Computer Solutions, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2,
|
|
* as published by the Free Software Foundation.
|
|
*/
|
|
|
|
/*
|
|
* USAGE:
|
|
* NOTES:
|
|
* 1. Make sure to enable the following options in your kernel config:
|
|
* CONFIG_SECURITY=y
|
|
* CONFIG_SECURITY_NETWORK=y
|
|
* CONFIG_SECURITY_NETWORK_XFRM=y
|
|
* CONFIG_SECURITY_SELINUX=m/y
|
|
* ISSUES:
|
|
* 1. Caching packets, so they are not dropped during negotiation
|
|
* 2. Emulating a reasonable SO_PEERSEC across machines
|
|
* 3. Testing addition of sk_policy's with security context via setsockopt
|
|
*/
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/security.h>
|
|
#include <linux/types.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/ip.h>
|
|
#include <linux/tcp.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/xfrm.h>
|
|
#include <net/xfrm.h>
|
|
#include <net/checksum.h>
|
|
#include <net/udp.h>
|
|
#include <linux/atomic.h>
|
|
|
|
#include "avc.h"
|
|
#include "objsec.h"
|
|
#include "xfrm.h"
|
|
|
|
/* Labeled XFRM instance counter */
|
|
atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0);
|
|
|
|
/*
|
|
* Returns true if the context is an LSM/SELinux context.
|
|
*/
|
|
static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
|
|
{
|
|
return (ctx &&
|
|
(ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
|
|
(ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
|
|
}
|
|
|
|
/*
|
|
* Returns true if the xfrm contains a security blob for SELinux.
|
|
*/
|
|
static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
|
|
{
|
|
return selinux_authorizable_ctx(x->security);
|
|
}
|
|
|
|
/*
|
|
* Allocates a xfrm_sec_state and populates it using the supplied security
|
|
* xfrm_user_sec_ctx context.
|
|
*/
|
|
static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
|
|
struct xfrm_user_sec_ctx *uctx,
|
|
gfp_t gfp)
|
|
{
|
|
int rc;
|
|
const struct task_security_struct *tsec = current_security();
|
|
struct xfrm_sec_ctx *ctx = NULL;
|
|
u32 str_len;
|
|
|
|
if (ctxp == NULL || uctx == NULL ||
|
|
uctx->ctx_doi != XFRM_SC_DOI_LSM ||
|
|
uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
|
|
return -EINVAL;
|
|
|
|
str_len = uctx->ctx_len;
|
|
if (str_len >= PAGE_SIZE)
|
|
return -ENOMEM;
|
|
|
|
ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp);
|
|
if (!ctx)
|
|
return -ENOMEM;
|
|
|
|
ctx->ctx_doi = XFRM_SC_DOI_LSM;
|
|
ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
|
|
ctx->ctx_len = str_len;
|
|
memcpy(ctx->ctx_str, &uctx[1], str_len);
|
|
ctx->ctx_str[str_len] = '\0';
|
|
rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
|
|
&ctx->ctx_sid, gfp);
|
|
if (rc)
|
|
goto err;
|
|
|
|
rc = avc_has_perm(&selinux_state,
|
|
tsec->sid, ctx->ctx_sid,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
|
|
if (rc)
|
|
goto err;
|
|
|
|
*ctxp = ctx;
|
|
atomic_inc(&selinux_xfrm_refcount);
|
|
return 0;
|
|
|
|
err:
|
|
kfree(ctx);
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* Free the xfrm_sec_ctx structure.
|
|
*/
|
|
static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
|
|
{
|
|
if (!ctx)
|
|
return;
|
|
|
|
atomic_dec(&selinux_xfrm_refcount);
|
|
kfree(ctx);
|
|
}
|
|
|
|
/*
|
|
* Authorize the deletion of a labeled SA or policy rule.
|
|
*/
|
|
static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
|
|
{
|
|
const struct task_security_struct *tsec = current_security();
|
|
|
|
if (!ctx)
|
|
return 0;
|
|
|
|
return avc_has_perm(&selinux_state,
|
|
tsec->sid, ctx->ctx_sid,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
|
|
NULL);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that authorizes that a flow can use a xfrm policy
|
|
* rule.
|
|
*/
|
|
int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
|
|
{
|
|
int rc;
|
|
|
|
/* All flows should be treated as polmatch'ing an otherwise applicable
|
|
* "non-labeled" policy. This would prevent inadvertent "leaks". */
|
|
if (!ctx)
|
|
return 0;
|
|
|
|
/* Context sid is either set to label or ANY_ASSOC */
|
|
if (!selinux_authorizable_ctx(ctx))
|
|
return -EINVAL;
|
|
|
|
rc = avc_has_perm(&selinux_state,
|
|
fl_secid, ctx->ctx_sid,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
|
|
return (rc == -EACCES ? -ESRCH : rc);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that authorizes that a state matches
|
|
* the given policy, flow combo.
|
|
*/
|
|
int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
|
|
struct xfrm_policy *xp,
|
|
const struct flowi *fl)
|
|
{
|
|
u32 state_sid;
|
|
|
|
if (!xp->security)
|
|
if (x->security)
|
|
/* unlabeled policy and labeled SA can't match */
|
|
return 0;
|
|
else
|
|
/* unlabeled policy and unlabeled SA match all flows */
|
|
return 1;
|
|
else
|
|
if (!x->security)
|
|
/* unlabeled SA and labeled policy can't match */
|
|
return 0;
|
|
else
|
|
if (!selinux_authorizable_xfrm(x))
|
|
/* Not a SELinux-labeled SA */
|
|
return 0;
|
|
|
|
state_sid = x->security->ctx_sid;
|
|
|
|
if (fl->flowi_secid != state_sid)
|
|
return 0;
|
|
|
|
/* We don't need a separate SA Vs. policy polmatch check since the SA
|
|
* is now of the same label as the flow and a flow Vs. policy polmatch
|
|
* check had already happened in selinux_xfrm_policy_lookup() above. */
|
|
return (avc_has_perm(&selinux_state,
|
|
fl->flowi_secid, state_sid,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
|
|
NULL) ? 0 : 1);
|
|
}
|
|
|
|
static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
|
|
{
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
struct xfrm_state *x;
|
|
|
|
if (dst == NULL)
|
|
return SECSID_NULL;
|
|
x = dst->xfrm;
|
|
if (x == NULL || !selinux_authorizable_xfrm(x))
|
|
return SECSID_NULL;
|
|
|
|
return x->security->ctx_sid;
|
|
}
|
|
|
|
static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
|
|
u32 *sid, int ckall)
|
|
{
|
|
u32 sid_session = SECSID_NULL;
|
|
struct sec_path *sp = skb->sp;
|
|
|
|
if (sp) {
|
|
int i;
|
|
|
|
for (i = sp->len - 1; i >= 0; i--) {
|
|
struct xfrm_state *x = sp->xvec[i];
|
|
if (selinux_authorizable_xfrm(x)) {
|
|
struct xfrm_sec_ctx *ctx = x->security;
|
|
|
|
if (sid_session == SECSID_NULL) {
|
|
sid_session = ctx->ctx_sid;
|
|
if (!ckall)
|
|
goto out;
|
|
} else if (sid_session != ctx->ctx_sid) {
|
|
*sid = SECSID_NULL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
out:
|
|
*sid = sid_session;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that checks and/or returns the xfrm sid for the
|
|
* incoming packet.
|
|
*/
|
|
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
|
|
{
|
|
if (skb == NULL) {
|
|
*sid = SECSID_NULL;
|
|
return 0;
|
|
}
|
|
return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
|
|
}
|
|
|
|
int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
|
|
{
|
|
int rc;
|
|
|
|
rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
|
|
if (rc == 0 && *sid == SECSID_NULL)
|
|
*sid = selinux_xfrm_skb_sid_egress(skb);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
|
|
*/
|
|
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
|
|
struct xfrm_user_sec_ctx *uctx,
|
|
gfp_t gfp)
|
|
{
|
|
return selinux_xfrm_alloc_user(ctxp, uctx, gfp);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that copies security data structure from old to new
|
|
* for policy cloning.
|
|
*/
|
|
int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
|
|
struct xfrm_sec_ctx **new_ctxp)
|
|
{
|
|
struct xfrm_sec_ctx *new_ctx;
|
|
|
|
if (!old_ctx)
|
|
return 0;
|
|
|
|
new_ctx = kmemdup(old_ctx, sizeof(*old_ctx) + old_ctx->ctx_len,
|
|
GFP_ATOMIC);
|
|
if (!new_ctx)
|
|
return -ENOMEM;
|
|
atomic_inc(&selinux_xfrm_refcount);
|
|
*new_ctxp = new_ctx;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that frees xfrm_sec_ctx security information.
|
|
*/
|
|
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
|
|
{
|
|
selinux_xfrm_free(ctx);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that authorizes deletion of labeled policies.
|
|
*/
|
|
int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
|
|
{
|
|
return selinux_xfrm_delete(ctx);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that allocates a xfrm_sec_state, populates it using
|
|
* the supplied security context, and assigns it to the xfrm_state.
|
|
*/
|
|
int selinux_xfrm_state_alloc(struct xfrm_state *x,
|
|
struct xfrm_user_sec_ctx *uctx)
|
|
{
|
|
return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that allocates a xfrm_sec_state and populates based
|
|
* on a secid.
|
|
*/
|
|
int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
|
|
struct xfrm_sec_ctx *polsec, u32 secid)
|
|
{
|
|
int rc;
|
|
struct xfrm_sec_ctx *ctx;
|
|
char *ctx_str = NULL;
|
|
u32 str_len;
|
|
|
|
if (!polsec)
|
|
return 0;
|
|
|
|
if (secid == 0)
|
|
return -EINVAL;
|
|
|
|
rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
|
|
&str_len);
|
|
if (rc)
|
|
return rc;
|
|
|
|
ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
|
|
if (!ctx) {
|
|
rc = -ENOMEM;
|
|
goto out;
|
|
}
|
|
|
|
ctx->ctx_doi = XFRM_SC_DOI_LSM;
|
|
ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
|
|
ctx->ctx_sid = secid;
|
|
ctx->ctx_len = str_len;
|
|
memcpy(ctx->ctx_str, ctx_str, str_len);
|
|
|
|
x->security = ctx;
|
|
atomic_inc(&selinux_xfrm_refcount);
|
|
out:
|
|
kfree(ctx_str);
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that frees xfrm_state security information.
|
|
*/
|
|
void selinux_xfrm_state_free(struct xfrm_state *x)
|
|
{
|
|
selinux_xfrm_free(x->security);
|
|
}
|
|
|
|
/*
|
|
* LSM hook implementation that authorizes deletion of labeled SAs.
|
|
*/
|
|
int selinux_xfrm_state_delete(struct xfrm_state *x)
|
|
{
|
|
return selinux_xfrm_delete(x->security);
|
|
}
|
|
|
|
/*
|
|
* LSM hook that controls access to unlabelled packets. If
|
|
* a xfrm_state is authorizable (defined by macro) then it was
|
|
* already authorized by the IPSec process. If not, then
|
|
* we need to check for unlabelled access since this may not have
|
|
* gone thru the IPSec process.
|
|
*/
|
|
int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
|
|
struct common_audit_data *ad)
|
|
{
|
|
int i;
|
|
struct sec_path *sp = skb->sp;
|
|
u32 peer_sid = SECINITSID_UNLABELED;
|
|
|
|
if (sp) {
|
|
for (i = 0; i < sp->len; i++) {
|
|
struct xfrm_state *x = sp->xvec[i];
|
|
|
|
if (x && selinux_authorizable_xfrm(x)) {
|
|
struct xfrm_sec_ctx *ctx = x->security;
|
|
peer_sid = ctx->ctx_sid;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* This check even when there's no association involved is intended,
|
|
* according to Trent Jaeger, to make sure a process can't engage in
|
|
* non-IPsec communication unless explicitly allowed by policy. */
|
|
return avc_has_perm(&selinux_state,
|
|
sk_sid, peer_sid,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
|
|
}
|
|
|
|
/*
|
|
* POSTROUTE_LAST hook's XFRM processing:
|
|
* If we have no security association, then we need to determine
|
|
* whether the socket is allowed to send to an unlabelled destination.
|
|
* If we do have a authorizable security association, then it has already been
|
|
* checked in the selinux_xfrm_state_pol_flow_match hook above.
|
|
*/
|
|
int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
|
|
struct common_audit_data *ad, u8 proto)
|
|
{
|
|
struct dst_entry *dst;
|
|
|
|
switch (proto) {
|
|
case IPPROTO_AH:
|
|
case IPPROTO_ESP:
|
|
case IPPROTO_COMP:
|
|
/* We should have already seen this packet once before it
|
|
* underwent xfrm(s). No need to subject it to the unlabeled
|
|
* check. */
|
|
return 0;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
dst = skb_dst(skb);
|
|
if (dst) {
|
|
struct dst_entry *iter;
|
|
|
|
for (iter = dst; iter != NULL; iter = iter->child) {
|
|
struct xfrm_state *x = iter->xfrm;
|
|
|
|
if (x && selinux_authorizable_xfrm(x))
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* This check even when there's no association involved is intended,
|
|
* according to Trent Jaeger, to make sure a process can't engage in
|
|
* non-IPsec communication unless explicitly allowed by policy. */
|
|
return avc_has_perm(&selinux_state, sk_sid, SECINITSID_UNLABELED,
|
|
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
|
|
}
|