diff options
author | 2021-12-17 06:55:39 -0500 | |
---|---|---|
committer | 2021-12-17 06:55:39 -0500 | |
commit | b4fcf1d1c9ef052ea04243f054b156331a0a7463 (patch) | |
tree | da35ed92a71abaa8ff1ad4a32fff29761db0fc95 | |
parent | Linux patch 5.4.166 (diff) | |
download | linux-patches-5.4-171.tar.gz linux-patches-5.4-171.tar.bz2 linux-patches-5.4-171.zip |
Linux patch 5.4.1675.4-171
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1166_linux-5.4.167.patch | 695 |
2 files changed, 699 insertions, 0 deletions
diff --git a/0000_README b/0000_README index c290221c..03c7ef31 100644 --- a/0000_README +++ b/0000_README @@ -707,6 +707,10 @@ Patch: 1165_linux-5.4.166.patch From: http://www.kernel.org Desc: Linux 5.4.166 +Patch: 1166_linux-5.4.167.patch +From: http://www.kernel.org +Desc: Linux 5.4.167 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1166_linux-5.4.167.patch b/1166_linux-5.4.167.patch new file mode 100644 index 00000000..98dd7071 --- /dev/null +++ b/1166_linux-5.4.167.patch @@ -0,0 +1,695 @@ +diff --git a/Makefile b/Makefile +index b1e5f7c6206ed..1045f7fc08503 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 166 ++SUBLEVEL = 167 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c +index 5a3641b5ec2cd..ff2cd985d20e0 100644 +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -176,11 +176,22 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low, + int pfn_valid(unsigned long pfn) + { + phys_addr_t addr = __pfn_to_phys(pfn); ++ unsigned long pageblock_size = PAGE_SIZE * pageblock_nr_pages; + + if (__phys_to_pfn(addr) != pfn) + return 0; + +- return memblock_is_map_memory(__pfn_to_phys(pfn)); ++ /* ++ * If address less than pageblock_size bytes away from a present ++ * memory chunk there still will be a memory map entry for it ++ * because we round freed memory map to the pageblock boundaries. ++ */ ++ if (memblock_overlaps_region(&memblock.memory, ++ ALIGN_DOWN(addr, pageblock_size), ++ pageblock_size)) ++ return 1; ++ ++ return 0; + } + EXPORT_SYMBOL(pfn_valid); + #endif +@@ -371,14 +382,14 @@ static void __init free_unused_memmap(void) + */ + start = min(start, + ALIGN(prev_end, PAGES_PER_SECTION)); +-#else ++#endif + /* +- * Align down here since the VM subsystem insists that the +- * memmap entries are valid from the bank start aligned to +- * MAX_ORDER_NR_PAGES. ++ * Align down here since many operations in VM subsystem ++ * presume that there are no holes in the memory map inside ++ * a pageblock + */ +- start = round_down(start, MAX_ORDER_NR_PAGES); +-#endif ++ start = round_down(start, pageblock_nr_pages); ++ + /* + * If we had a previous bank, and there is a space + * between the current bank and the previous, free it. +@@ -387,18 +398,20 @@ static void __init free_unused_memmap(void) + free_memmap(prev_end, start); + + /* +- * Align up here since the VM subsystem insists that the +- * memmap entries are valid from the bank end aligned to +- * MAX_ORDER_NR_PAGES. ++ * Align up here since many operations in VM subsystem ++ * presume that there are no holes in the memory map inside ++ * a pageblock + */ + prev_end = ALIGN(memblock_region_memory_end_pfn(reg), +- MAX_ORDER_NR_PAGES); ++ pageblock_nr_pages); + } + + #ifdef CONFIG_SPARSEMEM +- if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) ++ if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) { ++ prev_end = ALIGN(prev_end, pageblock_nr_pages); + free_memmap(prev_end, + ALIGN(prev_end, PAGES_PER_SECTION)); ++ } + #endif + } + +diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c +index d42b933161832..513c26b46db35 100644 +--- a/arch/arm/mm/ioremap.c ++++ b/arch/arm/mm/ioremap.c +@@ -27,6 +27,7 @@ + #include <linux/vmalloc.h> + #include <linux/io.h> + #include <linux/sizes.h> ++#include <linux/memblock.h> + + #include <asm/cp15.h> + #include <asm/cputype.h> +@@ -301,7 +302,8 @@ static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, + * Don't allow RAM to be mapped with mismatched attributes - this + * causes problems with ARMv6+ + */ +- if (WARN_ON(pfn_valid(pfn) && mtype != MT_MEMORY_RW)) ++ if (WARN_ON(memblock_is_map_memory(PFN_PHYS(pfn)) && ++ mtype != MT_MEMORY_RW)) + return NULL; + + area = get_vm_area_caller(size, VM_IOREMAP, caller); +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index 26408434b9bcf..be92e8dccda3d 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1501,11 +1501,13 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa, + + all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; + ++ if (all_cpus) ++ goto check_and_send_ipi; ++ + if (!sparse_banks_len) + goto ret_success; + +- if (!all_cpus && +- kvm_read_guest(kvm, ++ if (kvm_read_guest(kvm, + ingpa + offsetof(struct hv_send_ipi_ex, + vp_set.bank_contents), + sparse_banks, +@@ -1513,6 +1515,7 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *current_vcpu, u64 ingpa, u64 outgpa, + return HV_STATUS_INVALID_HYPERCALL_INPUT; + } + ++check_and_send_ipi: + if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) + return HV_STATUS_INVALID_HYPERCALL_INPUT; + +diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c +index ed3c4c42fc23b..d68d05d5d3838 100644 +--- a/drivers/char/agp/parisc-agp.c ++++ b/drivers/char/agp/parisc-agp.c +@@ -281,7 +281,7 @@ agp_ioc_init(void __iomem *ioc_regs) + return 0; + } + +-static int ++static int __init + lba_find_capability(int cap) + { + struct _parisc_agp_info *info = &parisc_agp_info; +@@ -366,7 +366,7 @@ fail: + return error; + } + +-static int ++static int __init + find_quicksilver(struct device *dev, void *data) + { + struct parisc_device **lba = data; +@@ -378,7 +378,7 @@ find_quicksilver(struct device *dev, void *data) + return 0; + } + +-static int ++static int __init + parisc_agp_init(void) + { + extern struct sba_device *sba_list; +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +index f0b001b3af578..883ee517673bd 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +@@ -221,6 +221,14 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) + ret = -EINVAL; + goto cleanup; + } ++ ++ if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) && ++ (aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) { ++ DRM_DEBUG_DRIVER("No DP connector available for CRC source\n"); ++ ret = -EINVAL; ++ goto cleanup; ++ } ++ + } + + if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index f25ac17f47fa9..95a5310e9e661 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -1546,6 +1546,10 @@ bool dc_is_stream_unchanged( + if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) + return false; + ++ // Only Have Audio left to check whether it is same or not. This is a corner case for Tiled sinks ++ if (old_stream->audio_info.mode_count != stream->audio_info.mode_count) ++ return false; ++ + return true; + } + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 5613234823f7d..423c4ae2be10d 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -1669,6 +1669,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, + if (!prop) { + DRM_DEV_DEBUG(dev, + "failed to find data lane mapping, using default\n"); ++ /* Set the number of date lanes to 4 by default. */ ++ msm_host->num_data_lanes = 4; + return 0; + } + +diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c +index 35c00420d855b..2eaed0008f376 100644 +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -588,15 +588,18 @@ static const struct file_operations i8k_fops = { + .unlocked_ioctl = i8k_ioctl, + }; + ++static struct proc_dir_entry *entry; ++ + static void __init i8k_init_procfs(void) + { + /* Register the proc entry */ +- proc_create("i8k", 0, NULL, &i8k_fops); ++ entry = proc_create("i8k", 0, NULL, &i8k_fops); + } + + static void __exit i8k_exit_procfs(void) + { +- remove_proc_entry("i8k", NULL); ++ if (entry) ++ remove_proc_entry("i8k", NULL); + } + + #else +diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c +index 1a33007b03e9e..1107a5e7229e4 100644 +--- a/drivers/i2c/busses/i2c-rk3x.c ++++ b/drivers/i2c/busses/i2c-rk3x.c +@@ -422,8 +422,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) + if (!(ipd & REG_INT_MBRF)) + return; + +- /* ack interrupt */ +- i2c_writel(i2c, REG_INT_MBRF, REG_IPD); ++ /* ack interrupt (read also produces a spurious START flag, clear it too) */ ++ i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); + + /* Can only handle a maximum of 32 bytes at a time */ + if (len > 32) +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index 426786a349c3c..dd029d91bbc2d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -663,7 +663,7 @@ void __init mlx4_en_init_ptys2ethtool_map(void) + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000, +- ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); ++ ETHTOOL_LINK_MODE_1000baseX_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000, + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000, +@@ -675,9 +675,9 @@ void __init mlx4_en_init_ptys2ethtool_map(void) + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000, +- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); ++ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000, +- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); ++ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT); + MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000, + ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT); +diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c +index 6684696fa4571..4b2819b0a05ab 100644 +--- a/kernel/bpf/devmap.c ++++ b/kernel/bpf/devmap.c +@@ -94,7 +94,7 @@ static struct hlist_head *dev_map_create_hash(unsigned int entries, + int i; + struct hlist_head *hash; + +- hash = bpf_map_area_alloc(entries * sizeof(*hash), numa_node); ++ hash = bpf_map_area_alloc((u64) entries * sizeof(*hash), numa_node); + if (hash != NULL) + for (i = 0; i < entries; i++) + INIT_HLIST_HEAD(&hash[i]); +@@ -159,7 +159,7 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr) + + spin_lock_init(&dtab->index_lock); + } else { +- dtab->netdev_map = bpf_map_area_alloc(dtab->map.max_entries * ++ dtab->netdev_map = bpf_map_area_alloc((u64) dtab->map.max_entries * + sizeof(struct bpf_dtab_netdev *), + dtab->map.numa_node); + if (!dtab->netdev_map) +diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c +index 10657b8dc2c2d..83c2a0598c648 100644 +--- a/kernel/trace/tracing_map.c ++++ b/kernel/trace/tracing_map.c +@@ -15,6 +15,7 @@ + #include <linux/jhash.h> + #include <linux/slab.h> + #include <linux/sort.h> ++#include <linux/kmemleak.h> + + #include "tracing_map.h" + #include "trace.h" +@@ -307,6 +308,7 @@ void tracing_map_array_free(struct tracing_map_array *a) + for (i = 0; i < a->n_pages; i++) { + if (!a->pages[i]) + break; ++ kmemleak_free(a->pages[i]); + free_page((unsigned long)a->pages[i]); + } + +@@ -342,6 +344,7 @@ struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, + a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL); + if (!a->pages[i]) + goto free; ++ kmemleak_alloc(a->pages[i], PAGE_SIZE, 1, GFP_KERNEL); + } + out: + return a; +diff --git a/mm/memblock.c b/mm/memblock.c +index 11f6ae37d6699..38cef8b6df050 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -164,6 +164,8 @@ bool __init_memblock memblock_overlaps_region(struct memblock_type *type, + { + unsigned long i; + ++ memblock_cap_size(base, &size); ++ + for (i = 0; i < type->cnt; i++) + if (memblock_addrs_overlap(base, size, type->regions[i].base, + type->regions[i].size)) +@@ -1760,7 +1762,6 @@ bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t siz + */ + bool __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) + { +- memblock_cap_size(base, &size); + return memblock_overlaps_region(&memblock.reserved, base, size); + } + +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index df52061f99f76..2646e8f98f67d 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -48,7 +48,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr) + if (err) + goto free_stab; + +- stab->sks = bpf_map_area_alloc(stab->map.max_entries * ++ stab->sks = bpf_map_area_alloc((u64) stab->map.max_entries * + sizeof(struct sock *), + stab->map.numa_node); + if (stab->sks) +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index cb35680db9b29..891e029ad0f89 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1862,6 +1862,11 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + if (msg->msg_flags&MSG_OOB) + return -EOPNOTSUPP; + ++ if (len == 0) { ++ pr_warn_once("Zero length message leads to an empty skb\n"); ++ return -ENODATA; ++ } ++ + err = scm_send(sock, msg, &scm, true); + if (err < 0) + return err; +diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c +index 0f61dad7256b8..4d90cbdc083b5 100644 +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -644,8 +644,10 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb) + { + struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; + +- nfc_device_iter_exit(iter); +- kfree(iter); ++ if (iter) { ++ nfc_device_iter_exit(iter); ++ kfree(iter); ++ } + + return 0; + } +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index f62adf3cfce89..a0afe49309c88 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -2250,6 +2250,43 @@ size_t security_policydb_len(struct selinux_state *state) + return len; + } + ++/** ++ * ocontext_to_sid - Helper to safely get sid for an ocontext ++ * @sidtab: SID table ++ * @c: ocontext structure ++ * @index: index of the context entry (0 or 1) ++ * @out_sid: pointer to the resulting SID value ++ * ++ * For all ocontexts except OCON_ISID the SID fields are populated ++ * on-demand when needed. Since updating the SID value is an SMP-sensitive ++ * operation, this helper must be used to do that safely. ++ * ++ * WARNING: This function may return -ESTALE, indicating that the caller ++ * must retry the operation after re-acquiring the policy pointer! ++ */ ++static int ocontext_to_sid(struct sidtab *sidtab, struct ocontext *c, ++ size_t index, u32 *out_sid) ++{ ++ int rc; ++ u32 sid; ++ ++ /* Ensure the associated sidtab entry is visible to this thread. */ ++ sid = smp_load_acquire(&c->sid[index]); ++ if (!sid) { ++ rc = sidtab_context_to_sid(sidtab, &c->context[index], &sid); ++ if (rc) ++ return rc; ++ ++ /* ++ * Ensure the new sidtab entry is visible to other threads ++ * when they see the SID. ++ */ ++ smp_store_release(&c->sid[index], sid); ++ } ++ *out_sid = sid; ++ return 0; ++} ++ + /** + * security_port_sid - Obtain the SID for a port. + * @protocol: protocol number +@@ -2262,10 +2299,12 @@ int security_port_sid(struct selinux_state *state, + struct policydb *policydb; + struct sidtab *sidtab; + struct ocontext *c; +- int rc = 0; ++ int rc; + + read_lock(&state->ss->policy_rwlock); + ++retry: ++ rc = 0; + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2279,14 +2318,11 @@ int security_port_sid(struct selinux_state *state, + } + + if (c) { +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, +- &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- } +- *out_sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, out_sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else { + *out_sid = SECINITSID_PORT; + } +@@ -2308,10 +2344,12 @@ int security_ib_pkey_sid(struct selinux_state *state, + struct policydb *policydb; + struct sidtab *sidtab; + struct ocontext *c; +- int rc = 0; ++ int rc; + + read_lock(&state->ss->policy_rwlock); + ++retry: ++ rc = 0; + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2326,14 +2364,11 @@ int security_ib_pkey_sid(struct selinux_state *state, + } + + if (c) { +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, +- &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- } +- *out_sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, out_sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else + *out_sid = SECINITSID_UNLABELED; + +@@ -2354,10 +2389,12 @@ int security_ib_endport_sid(struct selinux_state *state, + struct policydb *policydb; + struct sidtab *sidtab; + struct ocontext *c; +- int rc = 0; ++ int rc; + + read_lock(&state->ss->policy_rwlock); + ++retry: ++ rc = 0; + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2373,14 +2410,11 @@ int security_ib_endport_sid(struct selinux_state *state, + } + + if (c) { +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, +- &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- } +- *out_sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, out_sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else + *out_sid = SECINITSID_UNLABELED; + +@@ -2399,11 +2433,13 @@ int security_netif_sid(struct selinux_state *state, + { + struct policydb *policydb; + struct sidtab *sidtab; +- int rc = 0; ++ int rc; + struct ocontext *c; + + read_lock(&state->ss->policy_rwlock); + ++retry: ++ rc = 0; + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2415,19 +2451,11 @@ int security_netif_sid(struct selinux_state *state, + } + + if (c) { +- if (!c->sid[0] || !c->sid[1]) { +- rc = sidtab_context_to_sid(sidtab, +- &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- rc = sidtab_context_to_sid(sidtab, +- &c->context[1], +- &c->sid[1]); +- if (rc) +- goto out; +- } +- *if_sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, if_sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else + *if_sid = SECINITSID_NETIF; + +@@ -2469,6 +2497,7 @@ int security_node_sid(struct selinux_state *state, + + read_lock(&state->ss->policy_rwlock); + ++retry: + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2511,14 +2540,11 @@ int security_node_sid(struct selinux_state *state, + } + + if (c) { +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, +- &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- } +- *out_sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, out_sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else { + *out_sid = SECINITSID_NODE; + } +@@ -2677,7 +2703,7 @@ static inline int __security_genfs_sid(struct selinux_state *state, + u16 sclass; + struct genfs *genfs; + struct ocontext *c; +- int rc, cmp = 0; ++ int cmp = 0; + + while (path[0] == '/' && path[1] == '/') + path++; +@@ -2691,9 +2717,8 @@ static inline int __security_genfs_sid(struct selinux_state *state, + break; + } + +- rc = -ENOENT; + if (!genfs || cmp) +- goto out; ++ return -ENOENT; + + for (c = genfs->head; c; c = c->next) { + len = strlen(c->u.name); +@@ -2702,20 +2727,10 @@ static inline int __security_genfs_sid(struct selinux_state *state, + break; + } + +- rc = -ENOENT; + if (!c) +- goto out; +- +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, &c->context[0], &c->sid[0]); +- if (rc) +- goto out; +- } ++ return -ENOENT; + +- *sid = c->sid[0]; +- rc = 0; +-out: +- return rc; ++ return ocontext_to_sid(sidtab, c, 0, sid); + } + + /** +@@ -2750,13 +2765,15 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) + { + struct policydb *policydb; + struct sidtab *sidtab; +- int rc = 0; ++ int rc; + struct ocontext *c; + struct superblock_security_struct *sbsec = sb->s_security; + const char *fstype = sb->s_type->name; + + read_lock(&state->ss->policy_rwlock); + ++retry: ++ rc = 0; + policydb = &state->ss->policydb; + sidtab = state->ss->sidtab; + +@@ -2769,13 +2786,11 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) + + if (c) { + sbsec->behavior = c->v.behavior; +- if (!c->sid[0]) { +- rc = sidtab_context_to_sid(sidtab, &c->context[0], +- &c->sid[0]); +- if (rc) +- goto out; +- } +- sbsec->sid = c->sid[0]; ++ rc = ocontext_to_sid(sidtab, c, 0, &sbsec->sid); ++ if (rc == -ESTALE) ++ goto retry; ++ if (rc) ++ goto out; + } else { + rc = __security_genfs_sid(state, fstype, "/", SECCLASS_DIR, + &sbsec->sid); |