Skip to content

Commit

Permalink
treewide: Change list_sort to use const pointers
Browse files Browse the repository at this point in the history
[ Upstream commit 4f0f586 ]

list_sort() internally casts the comparison function passed to it
to a different type with constant struct list_head pointers, and
uses this pointer to call the functions, which trips indirect call
Control-Flow Integrity (CFI) checking.

Instead of removing the consts, this change defines the
list_cmp_func_t type and changes the comparison function types of
all list_sort() callers to use const pointers, thus avoiding type
mismatches.

Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210408182843.1754385-10-samitolvanen@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
samitolvanen authored and gregkh committed Sep 30, 2021
1 parent 419fab1 commit 55e6f8b
Show file tree
Hide file tree
Showing 41 changed files with 90 additions and 72 deletions.
8 changes: 4 additions & 4 deletions arch/arm64/kvm/vgic/vgic-its.c
Expand Up @@ -2190,8 +2190,8 @@ static int vgic_its_restore_ite(struct vgic_its *its, u32 event_id,
return offset;
}

static int vgic_its_ite_cmp(void *priv, struct list_head *a,
struct list_head *b)
static int vgic_its_ite_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct its_ite *itea = container_of(a, struct its_ite, ite_list);
struct its_ite *iteb = container_of(b, struct its_ite, ite_list);
Expand Down Expand Up @@ -2329,8 +2329,8 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
return offset;
}

static int vgic_its_device_cmp(void *priv, struct list_head *a,
struct list_head *b)
static int vgic_its_device_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct its_device *deva = container_of(a, struct its_device, dev_list);
struct its_device *devb = container_of(b, struct its_device, dev_list);
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kvm/vgic/vgic.c
Expand Up @@ -255,7 +255,8 @@ static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq)
* Return negative if "a" sorts before "b", 0 to preserve order, and positive
* to sort "b" before "a".
*/
static int vgic_irq_cmp(void *priv, struct list_head *a, struct list_head *b)
static int vgic_irq_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct vgic_irq *irqa = container_of(a, struct vgic_irq, ap_list);
struct vgic_irq *irqb = container_of(b, struct vgic_irq, ap_list);
Expand Down
3 changes: 2 additions & 1 deletion block/blk-mq-sched.c
Expand Up @@ -75,7 +75,8 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx)
blk_mq_run_hw_queue(hctx, true);
}

static int sched_rq_cmp(void *priv, struct list_head *a, struct list_head *b)
static int sched_rq_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct request *rqa = container_of(a, struct request, queuelist);
struct request *rqb = container_of(b, struct request, queuelist);
Expand Down
3 changes: 2 additions & 1 deletion block/blk-mq.c
Expand Up @@ -1866,7 +1866,8 @@ void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
spin_unlock(&ctx->lock);
}

static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b)
static int plug_rq_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct request *rqa = container_of(a, struct request, queuelist);
struct request *rqb = container_of(b, struct request, queuelist);
Expand Down
3 changes: 2 additions & 1 deletion drivers/acpi/nfit/core.c
Expand Up @@ -1194,7 +1194,8 @@ static int __nfit_mem_init(struct acpi_nfit_desc *acpi_desc,
return 0;
}

static int nfit_mem_cmp(void *priv, struct list_head *_a, struct list_head *_b)
static int nfit_mem_cmp(void *priv, const struct list_head *_a,
const struct list_head *_b)
{
struct nfit_mem *a = container_of(_a, typeof(*a), list);
struct nfit_mem *b = container_of(_b, typeof(*b), list);
Expand Down
3 changes: 2 additions & 1 deletion drivers/acpi/numa/hmat.c
Expand Up @@ -558,7 +558,8 @@ static bool hmat_update_best(u8 type, u32 value, u32 *best)
return updated;
}

static int initiator_cmp(void *priv, struct list_head *a, struct list_head *b)
static int initiator_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct memory_initiator *ia;
struct memory_initiator *ib;
Expand Down
4 changes: 2 additions & 2 deletions drivers/clk/keystone/sci-clk.c
Expand Up @@ -503,8 +503,8 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)

#else

static int _cmp_sci_clk_list(void *priv, struct list_head *a,
struct list_head *b)
static int _cmp_sci_clk_list(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct sci_clk *ca = container_of(a, struct sci_clk, node);
struct sci_clk *cb = container_of(b, struct sci_clk, node);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_modes.c
Expand Up @@ -1290,7 +1290,8 @@ EXPORT_SYMBOL(drm_mode_prune_invalid);
* Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
* positive if @lh_b is better than @lh_a.
*/
static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b)
static int drm_mode_compare(void *priv, const struct list_head *lh_a,
const struct list_head *lh_b)
{
struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head);
struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gt/intel_engine_user.c
Expand Up @@ -49,7 +49,8 @@ static const u8 uabi_classes[] = {
[VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
};

static int engine_cmp(void *priv, struct list_head *A, struct list_head *B)
static int engine_cmp(void *priv, const struct list_head *A,
const struct list_head *B)
{
const struct intel_engine_cs *a =
container_of((struct rb_node *)A, typeof(*a), uabi_node);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gvt/debugfs.c
Expand Up @@ -41,7 +41,7 @@ struct diff_mmio {

/* Compare two diff_mmio items. */
static int mmio_offset_compare(void *priv,
struct list_head *a, struct list_head *b)
const struct list_head *a, const struct list_head *b)
{
struct diff_mmio *ma;
struct diff_mmio *mb;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
Expand Up @@ -1075,7 +1075,8 @@ static int igt_ppgtt_shrink_boom(void *arg)
return exercise_ppgtt(arg, shrink_boom);
}

static int sort_holes(void *priv, struct list_head *A, struct list_head *B)
static int sort_holes(void *priv, const struct list_head *A,
const struct list_head *B)
{
struct drm_mm_node *a = list_entry(A, typeof(*a), hole_stack);
struct drm_mm_node *b = list_entry(B, typeof(*b), hole_stack);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/radeon/radeon_cs.c
Expand Up @@ -394,8 +394,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
return 0;
}

static int cmp_size_smaller_first(void *priv, struct list_head *a,
struct list_head *b)
static int cmp_size_smaller_first(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head);
struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head);
Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
Expand Up @@ -83,7 +83,8 @@ usnic_uiom_interval_node_alloc(long int start, long int last, int ref_cnt,
return interval;
}

static int interval_cmp(void *priv, struct list_head *a, struct list_head *b)
static int interval_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct usnic_uiom_interval_node *node_a, *node_b;

Expand Down
2 changes: 1 addition & 1 deletion drivers/interconnect/qcom/bcm-voter.c
Expand Up @@ -39,7 +39,7 @@ struct bcm_voter {
u32 tcs_wait;
};

static int cmp_vcd(void *priv, struct list_head *a, struct list_head *b)
static int cmp_vcd(void *priv, const struct list_head *a, const struct list_head *b)
{
const struct qcom_icc_bcm *bcm_a =
list_entry(a, struct qcom_icc_bcm, list);
Expand Down
3 changes: 2 additions & 1 deletion drivers/md/raid5.c
Expand Up @@ -953,7 +953,8 @@ static void dispatch_bio_list(struct bio_list *tmp)
submit_bio_noacct(bio);
}

static int cmp_stripe(void *priv, struct list_head *a, struct list_head *b)
static int cmp_stripe(void *priv, const struct list_head *a,
const struct list_head *b)
{
const struct r5pending_data *da = list_entry(a,
struct r5pending_data, sibling);
Expand Down
4 changes: 2 additions & 2 deletions drivers/misc/sram.c
Expand Up @@ -144,8 +144,8 @@ static void sram_free_partitions(struct sram_dev *sram)
}
}

static int sram_reserve_cmp(void *priv, struct list_head *a,
struct list_head *b)
static int sram_reserve_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct sram_reserve *ra = list_entry(a, struct sram_reserve, list);
struct sram_reserve *rb = list_entry(b, struct sram_reserve, list);
Expand Down
3 changes: 2 additions & 1 deletion drivers/nvme/host/core.c
Expand Up @@ -3801,7 +3801,8 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
return ret;
}

static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
static int ns_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
Expand Down
3 changes: 2 additions & 1 deletion drivers/pci/controller/cadence/pcie-cadence-host.c
Expand Up @@ -345,7 +345,8 @@ static int cdns_pcie_host_bar_config(struct cdns_pcie_rc *rc,
return 0;
}

static int cdns_pcie_host_dma_ranges_cmp(void *priv, struct list_head *a, struct list_head *b)
static int cdns_pcie_host_dma_ranges_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct resource_entry *entry1, *entry2;

Expand Down
3 changes: 2 additions & 1 deletion drivers/spi/spi-loopback-test.c
Expand Up @@ -454,7 +454,8 @@ struct rx_ranges {
u8 *end;
};

static int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b)
static int rx_ranges_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list);
struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list);
Expand Down
3 changes: 2 additions & 1 deletion fs/btrfs/raid56.c
Expand Up @@ -1646,7 +1646,8 @@ struct btrfs_plug_cb {
/*
* rbios on the plug list are sorted for easier merging.
*/
static int plug_cmp(void *priv, struct list_head *a, struct list_head *b)
static int plug_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct btrfs_raid_bio *ra = container_of(a, struct btrfs_raid_bio,
plug_list);
Expand Down
3 changes: 2 additions & 1 deletion fs/btrfs/tree-log.c
Expand Up @@ -4070,7 +4070,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
return ret;
}

static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
static int extent_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct extent_map *em1, *em2;

Expand Down
3 changes: 2 additions & 1 deletion fs/btrfs/volumes.c
Expand Up @@ -1226,7 +1226,8 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
return 0;
}

static int devid_cmp(void *priv, struct list_head *a, struct list_head *b)
static int devid_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct btrfs_device *dev1, *dev2;

Expand Down
4 changes: 2 additions & 2 deletions fs/ext4/fsmap.c
Expand Up @@ -354,8 +354,8 @@ static unsigned int ext4_getfsmap_find_sb(struct super_block *sb,

/* Compare two fsmap items. */
static int ext4_getfsmap_compare(void *priv,
struct list_head *a,
struct list_head *b)
const struct list_head *a,
const struct list_head *b)
{
struct ext4_fsmap *fa;
struct ext4_fsmap *fb;
Expand Down
3 changes: 2 additions & 1 deletion fs/gfs2/glock.c
Expand Up @@ -1744,7 +1744,8 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
spin_unlock(&gl->gl_lockref.lock);
}

static int glock_cmp(void *priv, struct list_head *a, struct list_head *b)
static int glock_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct gfs2_glock *gla, *glb;

Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/log.c
Expand Up @@ -605,7 +605,7 @@ void log_flush_wait(struct gfs2_sbd *sdp)
}
}

static int ip_cmp(void *priv, struct list_head *a, struct list_head *b)
static int ip_cmp(void *priv, const struct list_head *a, const struct list_head *b)
{
struct gfs2_inode *ipa, *ipb;

Expand Down
3 changes: 2 additions & 1 deletion fs/gfs2/lops.c
Expand Up @@ -627,7 +627,8 @@ static void gfs2_check_magic(struct buffer_head *bh)
kunmap_atomic(kaddr);
}

static int blocknr_cmp(void *priv, struct list_head *a, struct list_head *b)
static int blocknr_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct gfs2_bufdata *bda, *bdb;

Expand Down
3 changes: 2 additions & 1 deletion fs/iomap/buffered-io.c
Expand Up @@ -1155,7 +1155,8 @@ iomap_ioend_try_merge(struct iomap_ioend *ioend, struct list_head *more_ioends,
EXPORT_SYMBOL_GPL(iomap_ioend_try_merge);

static int
iomap_ioend_compare(void *priv, struct list_head *a, struct list_head *b)
iomap_ioend_compare(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct iomap_ioend *ia = container_of(a, struct iomap_ioend, io_list);
struct iomap_ioend *ib = container_of(b, struct iomap_ioend, io_list);
Expand Down
7 changes: 4 additions & 3 deletions fs/ubifs/gc.c
Expand Up @@ -102,7 +102,8 @@ static int switch_gc_head(struct ubifs_info *c)
* This function compares data nodes @a and @b. Returns %1 if @a has greater
* inode or block number, and %-1 otherwise.
*/
static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
static int data_nodes_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
ino_t inuma, inumb;
struct ubifs_info *c = priv;
Expand Down Expand Up @@ -145,8 +146,8 @@ static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
* first and sorted by length in descending order. Directory entry nodes go
* after inode nodes and are sorted in ascending hash valuer order.
*/
static int nondata_nodes_cmp(void *priv, struct list_head *a,
struct list_head *b)
static int nondata_nodes_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
ino_t inuma, inumb;
struct ubifs_info *c = priv;
Expand Down
4 changes: 2 additions & 2 deletions fs/ubifs/replay.c
Expand Up @@ -299,8 +299,8 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
* entries @a and @b by comparing their sequence numer. Returns %1 if @a has
* greater sequence number and %-1 otherwise.
*/
static int replay_entries_cmp(void *priv, struct list_head *a,
struct list_head *b)
static int replay_entries_cmp(void *priv, const struct list_head *a,
const struct list_head *b)
{
struct ubifs_info *c = priv;
struct replay_entry *ra, *rb;
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/scrub/bitmap.c
Expand Up @@ -63,8 +63,8 @@ xbitmap_init(
static int
xbitmap_range_cmp(
void *priv,
struct list_head *a,
struct list_head *b)
const struct list_head *a,
const struct list_head *b)
{
struct xbitmap_range *ap;
struct xbitmap_range *bp;
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/xfs_bmap_item.c
Expand Up @@ -265,8 +265,8 @@ xfs_trans_log_finish_bmap_update(
static int
xfs_bmap_update_diff_items(
void *priv,
struct list_head *a,
struct list_head *b)
const struct list_head *a,
const struct list_head *b)
{
struct xfs_bmap_intent *ba;
struct xfs_bmap_intent *bb;
Expand Down
6 changes: 3 additions & 3 deletions fs/xfs/xfs_buf.c
Expand Up @@ -2114,9 +2114,9 @@ xfs_buf_delwri_queue(
*/
static int
xfs_buf_cmp(
void *priv,
struct list_head *a,
struct list_head *b)
void *priv,
const struct list_head *a,
const struct list_head *b)
{
struct xfs_buf *ap = container_of(a, struct xfs_buf, b_list);
struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list);
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/xfs_extent_busy.c
Expand Up @@ -643,8 +643,8 @@ xfs_extent_busy_wait_all(
int
xfs_extent_busy_ag_cmp(
void *priv,
struct list_head *l1,
struct list_head *l2)
const struct list_head *l1,
const struct list_head *l2)
{
struct xfs_extent_busy *b1 =
container_of(l1, struct xfs_extent_busy, list);
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/xfs_extent_busy.h
Expand Up @@ -58,7 +58,8 @@ void
xfs_extent_busy_wait_all(struct xfs_mount *mp);

int
xfs_extent_busy_ag_cmp(void *priv, struct list_head *a, struct list_head *b);
xfs_extent_busy_ag_cmp(void *priv, const struct list_head *a,
const struct list_head *b);

static inline void xfs_extent_busy_sort(struct list_head *list)
{
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/xfs_extfree_item.c
Expand Up @@ -397,8 +397,8 @@ xfs_trans_free_extent(
static int
xfs_extent_free_diff_items(
void *priv,
struct list_head *a,
struct list_head *b)
const struct list_head *a,
const struct list_head *b)
{
struct xfs_mount *mp = priv;
struct xfs_extent_free_item *ra;
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/xfs_refcount_item.c
Expand Up @@ -269,8 +269,8 @@ xfs_trans_log_finish_refcount_update(
static int
xfs_refcount_update_diff_items(
void *priv,
struct list_head *a,
struct list_head *b)
const struct list_head *a,
const struct list_head *b)
{
struct xfs_mount *mp = priv;
struct xfs_refcount_intent *ra;
Expand Down

0 comments on commit 55e6f8b

Please sign in to comment.