From b01615d5ac86913da1e092d0378bfb8f0e72af30 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Thu, 14 Feb 2013 23:37:43 -0500 Subject: [PATCH] Constify structures containing function pointers The PaX team modified the kernel's modpost to report writeable function pointers as section mismatches because they are potential exploit targets. We could ignore the warnings, but their presence can obscure actual issues. Proper const correctness can also catch programming mistakes. Building the kernel modules against a PaX/GrSecurity patched Linux 3.4.2 kernel reports 133 section mismatches prior to this patch. This patch eliminates 130 of them. The quantity of writeable function pointers eliminated by constifying each structure is as follows: vdev_opts_t 52 zil_replay_func_t 24 zio_compress_info_t 24 zio_checksum_info_t 9 space_map_ops_t 7 arc_byteswap_func_t 5 The remaining 3 writeable function pointers cannot be addressed by this patch. 2 of them are in zpl_fs_type. The kernel's sget function requires that this be non-const. The final writeable function pointer is created by SPL_SHRINKER_DECLARE. The kernel's set_shrinker() and remove_shrinker() functions also require that this be non-const. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf Closes #1300 --- cmd/ztest/ztest.c | 12 +++++------ include/sys/dmu.h | 6 +++--- include/sys/space_map.h | 2 +- include/sys/vdev_impl.h | 2 +- include/sys/zfs_znode.h | 2 +- include/sys/zil.h | 4 ++-- include/sys/zio_checksum.h | 2 +- include/sys/zio_compress.h | 2 +- module/zfs/arc.c | 8 +++---- module/zfs/sa.c | 2 +- module/zfs/zfs_replay.c | 44 +++++++++++++++++++------------------- module/zfs/zil.c | 4 ++-- module/zfs/zvol.c | 28 ++++++++++++------------ 13 files changed, 59 insertions(+), 59 deletions(-) diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 07b81cc27..bb495b6a2 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -1792,19 +1792,19 @@ ztest_replay_setattr(ztest_ds_t *zd, lr_setattr_t *lr, boolean_t byteswap) return (0); } -zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = { +zil_replay_func_t ztest_replay_vector[TX_MAX_TYPE] = { NULL, /* 0 no such transaction type */ - (zil_replay_func_t *)ztest_replay_create, /* TX_CREATE */ + (zil_replay_func_t)ztest_replay_create, /* TX_CREATE */ NULL, /* TX_MKDIR */ NULL, /* TX_MKXATTR */ NULL, /* TX_SYMLINK */ - (zil_replay_func_t *)ztest_replay_remove, /* TX_REMOVE */ + (zil_replay_func_t)ztest_replay_remove, /* TX_REMOVE */ NULL, /* TX_RMDIR */ NULL, /* TX_LINK */ NULL, /* TX_RENAME */ - (zil_replay_func_t *)ztest_replay_write, /* TX_WRITE */ - (zil_replay_func_t *)ztest_replay_truncate, /* TX_TRUNCATE */ - (zil_replay_func_t *)ztest_replay_setattr, /* TX_SETATTR */ + (zil_replay_func_t)ztest_replay_write, /* TX_WRITE */ + (zil_replay_func_t)ztest_replay_truncate, /* TX_TRUNCATE */ + (zil_replay_func_t)ztest_replay_setattr, /* TX_SETATTR */ NULL, /* TX_ACL */ NULL, /* TX_CREATE_ACL */ NULL, /* TX_CREATE_ATTR */ diff --git a/include/sys/dmu.h b/include/sys/dmu.h index 2a3a76486..eb6a465c4 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -641,7 +641,7 @@ typedef struct dmu_object_info { uint64_t doi_fill_count; /* number of non-empty blocks */ } dmu_object_info_t; -typedef void arc_byteswap_func_t(void *buf, size_t size); +typedef void (*const arc_byteswap_func_t)(void *buf, size_t size); typedef struct dmu_object_type_info { dmu_object_byteswap_t ot_byteswap; @@ -649,8 +649,8 @@ typedef struct dmu_object_type_info { char *ot_name; } dmu_object_type_info_t; -typedef struct dmu_object_byteswap_info { - arc_byteswap_func_t *ob_func; +typedef const struct dmu_object_byteswap_info { + arc_byteswap_func_t ob_func; char *ob_name; } dmu_object_byteswap_info_t; diff --git a/include/sys/space_map.h b/include/sys/space_map.h index 6f935c9db..332299724 100644 --- a/include/sys/space_map.h +++ b/include/sys/space_map.h @@ -33,7 +33,7 @@ extern "C" { #endif -typedef struct space_map_ops space_map_ops_t; +typedef const struct space_map_ops space_map_ops_t; typedef struct space_map { avl_tree_t sm_root; /* AVL tree of map segments */ diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h index 4133f2cf3..964ee2407 100644 --- a/include/sys/vdev_impl.h +++ b/include/sys/vdev_impl.h @@ -67,7 +67,7 @@ typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef void vdev_hold_func_t(vdev_t *vd); typedef void vdev_rele_func_t(vdev_t *vd); -typedef struct vdev_ops { +typedef const struct vdev_ops { vdev_open_func_t *vdev_op_open; vdev_close_func_t *vdev_op_close; vdev_asize_func_t *vdev_op_asize; diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 41233547b..bdddcc366 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -371,7 +371,7 @@ extern void zfs_unmap_page(page_t *, caddr_t); #endif /* HAVE_UIO_RW */ extern zil_get_data_t zfs_get_data; -extern zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE]; +extern zil_replay_func_t zfs_replay_vector[TX_MAX_TYPE]; extern int zfsfstype; #endif /* _KERNEL */ diff --git a/include/sys/zil.h b/include/sys/zil.h index f786f0c9f..589e28f83 100644 --- a/include/sys/zil.h +++ b/include/sys/zil.h @@ -436,7 +436,7 @@ typedef int zil_parse_blk_func_t(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t txg); typedef int zil_parse_lr_func_t(zilog_t *zilog, lr_t *lr, void *arg, uint64_t txg); -typedef int zil_replay_func_t(void *, char *, boolean_t); +typedef int (*const zil_replay_func_t)(void *, char *, boolean_t); typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf, zio_t *zio); extern int zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func, @@ -452,7 +452,7 @@ extern zilog_t *zil_open(objset_t *os, zil_get_data_t *get_data); extern void zil_close(zilog_t *zilog); extern void zil_replay(objset_t *os, void *arg, - zil_replay_func_t *replay_func[TX_MAX_TYPE]); + zil_replay_func_t replay_func[TX_MAX_TYPE]); extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx); extern void zil_destroy(zilog_t *zilog, boolean_t keep_first); extern void zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx); diff --git a/include/sys/zio_checksum.h b/include/sys/zio_checksum.h index 0956c04ab..de89bc9a7 100644 --- a/include/sys/zio_checksum.h +++ b/include/sys/zio_checksum.h @@ -39,7 +39,7 @@ typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp); /* * Information about each checksum function. */ -typedef struct zio_checksum_info { +typedef const struct zio_checksum_info { zio_checksum_t *ci_func[2]; /* checksum function for each byteorder */ int ci_correctable; /* number of correctable bits */ int ci_eck; /* uses zio embedded checksum? */ diff --git a/include/sys/zio_compress.h b/include/sys/zio_compress.h index 49946af4b..bd051f185 100644 --- a/include/sys/zio_compress.h +++ b/include/sys/zio_compress.h @@ -44,7 +44,7 @@ typedef int zio_decompress_func_t(void *src, void *dst, /* * Information about each compression function. */ -typedef struct zio_compress_info { +typedef const struct zio_compress_info { zio_compress_func_t *ci_compress; /* compression function */ zio_decompress_func_t *ci_decompress; /* decompression function */ int ci_level; /* level parameter */ diff --git a/module/zfs/arc.c b/module/zfs/arc.c index b7499ee96..da070cd26 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -2802,10 +2802,10 @@ arc_read_done(zio_t *zio) if (BP_SHOULD_BYTESWAP(zio->io_bp) && zio->io_error == 0) { dmu_object_byteswap_t bswap = DMU_OT_BYTESWAP(BP_GET_TYPE(zio->io_bp)); - arc_byteswap_func_t *func = BP_GET_LEVEL(zio->io_bp) > 0 ? - byteswap_uint64_array : - dmu_ot_byteswap[bswap].ob_func; - func(buf->b_data, hdr->b_size); + if (BP_GET_LEVEL(zio->io_bp) > 0) + byteswap_uint64_array(buf->b_data, hdr->b_size); + else + dmu_ot_byteswap[bswap].ob_func(buf->b_data, hdr->b_size); } arc_cksum_compute(buf, B_FALSE); diff --git a/module/zfs/sa.c b/module/zfs/sa.c index f4d264f71..581cf4b0d 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -136,7 +136,7 @@ static int sa_modify_attrs(sa_handle_t *hdl, sa_attr_type_t newattr, sa_data_op_t action, sa_data_locator_t *locator, void *datastart, uint16_t buflen, dmu_tx_t *tx); -arc_byteswap_func_t *sa_bswap_table[] = { +arc_byteswap_func_t sa_bswap_table[] = { byteswap_uint64_array, byteswap_uint32_array, byteswap_uint16_array, diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index aa6366e11..813250c37 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -910,26 +910,26 @@ zfs_replay_acl(zfs_sb_t *zsb, lr_acl_t *lr, boolean_t byteswap) /* * Callback vectors for replaying records */ -zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE] = { - (zil_replay_func_t *)zfs_replay_error, /* no such type */ - (zil_replay_func_t *)zfs_replay_create, /* TX_CREATE */ - (zil_replay_func_t *)zfs_replay_create, /* TX_MKDIR */ - (zil_replay_func_t *)zfs_replay_create, /* TX_MKXATTR */ - (zil_replay_func_t *)zfs_replay_create, /* TX_SYMLINK */ - (zil_replay_func_t *)zfs_replay_remove, /* TX_REMOVE */ - (zil_replay_func_t *)zfs_replay_remove, /* TX_RMDIR */ - (zil_replay_func_t *)zfs_replay_link, /* TX_LINK */ - (zil_replay_func_t *)zfs_replay_rename, /* TX_RENAME */ - (zil_replay_func_t *)zfs_replay_write, /* TX_WRITE */ - (zil_replay_func_t *)zfs_replay_truncate, /* TX_TRUNCATE */ - (zil_replay_func_t *)zfs_replay_setattr, /* TX_SETATTR */ - (zil_replay_func_t *)zfs_replay_acl_v0, /* TX_ACL_V0 */ - (zil_replay_func_t *)zfs_replay_acl, /* TX_ACL */ - (zil_replay_func_t *)zfs_replay_create_acl, /* TX_CREATE_ACL */ - (zil_replay_func_t *)zfs_replay_create, /* TX_CREATE_ATTR */ - (zil_replay_func_t *)zfs_replay_create_acl, /* TX_CREATE_ACL_ATTR */ - (zil_replay_func_t *)zfs_replay_create_acl, /* TX_MKDIR_ACL */ - (zil_replay_func_t *)zfs_replay_create, /* TX_MKDIR_ATTR */ - (zil_replay_func_t *)zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */ - (zil_replay_func_t *)zfs_replay_write2, /* TX_WRITE2 */ +zil_replay_func_t zfs_replay_vector[TX_MAX_TYPE] = { + (zil_replay_func_t)zfs_replay_error, /* no such type */ + (zil_replay_func_t)zfs_replay_create, /* TX_CREATE */ + (zil_replay_func_t)zfs_replay_create, /* TX_MKDIR */ + (zil_replay_func_t)zfs_replay_create, /* TX_MKXATTR */ + (zil_replay_func_t)zfs_replay_create, /* TX_SYMLINK */ + (zil_replay_func_t)zfs_replay_remove, /* TX_REMOVE */ + (zil_replay_func_t)zfs_replay_remove, /* TX_RMDIR */ + (zil_replay_func_t)zfs_replay_link, /* TX_LINK */ + (zil_replay_func_t)zfs_replay_rename, /* TX_RENAME */ + (zil_replay_func_t)zfs_replay_write, /* TX_WRITE */ + (zil_replay_func_t)zfs_replay_truncate, /* TX_TRUNCATE */ + (zil_replay_func_t)zfs_replay_setattr, /* TX_SETATTR */ + (zil_replay_func_t)zfs_replay_acl_v0, /* TX_ACL_V0 */ + (zil_replay_func_t)zfs_replay_acl, /* TX_ACL */ + (zil_replay_func_t)zfs_replay_create_acl, /* TX_CREATE_ACL */ + (zil_replay_func_t)zfs_replay_create, /* TX_CREATE_ATTR */ + (zil_replay_func_t)zfs_replay_create_acl, /* TX_CREATE_ACL_ATTR */ + (zil_replay_func_t)zfs_replay_create_acl, /* TX_MKDIR_ACL */ + (zil_replay_func_t)zfs_replay_create, /* TX_MKDIR_ATTR */ + (zil_replay_func_t)zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */ + (zil_replay_func_t)zfs_replay_write2, /* TX_WRITE2 */ }; diff --git a/module/zfs/zil.c b/module/zfs/zil.c index c9618c13e..99d932fc0 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -1956,7 +1956,7 @@ zil_resume(zilog_t *zilog) } typedef struct zil_replay_arg { - zil_replay_func_t **zr_replay; + zil_replay_func_t *zr_replay; void *zr_arg; boolean_t zr_byteswap; char *zr_lr; @@ -2075,7 +2075,7 @@ zil_incr_blks(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) * If this dataset has a non-empty intent log, replay it and destroy it. */ void -zil_replay(objset_t *os, void *arg, zil_replay_func_t *replay_func[TX_MAX_TYPE]) +zil_replay(objset_t *os, void *arg, zil_replay_func_t replay_func[TX_MAX_TYPE]) { zilog_t *zilog = dmu_objset_zil(os); const zil_header_t *zh = zilog->zl_header; diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index c6cfac26d..f8e325676 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -453,20 +453,20 @@ zvol_replay_err(zvol_state_t *zv, lr_t *lr, boolean_t byteswap) * Callback vectors for replaying records. * Only TX_WRITE is needed for zvol. */ -zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = { - (zil_replay_func_t *)zvol_replay_err, /* no such transaction type */ - (zil_replay_func_t *)zvol_replay_err, /* TX_CREATE */ - (zil_replay_func_t *)zvol_replay_err, /* TX_MKDIR */ - (zil_replay_func_t *)zvol_replay_err, /* TX_MKXATTR */ - (zil_replay_func_t *)zvol_replay_err, /* TX_SYMLINK */ - (zil_replay_func_t *)zvol_replay_err, /* TX_REMOVE */ - (zil_replay_func_t *)zvol_replay_err, /* TX_RMDIR */ - (zil_replay_func_t *)zvol_replay_err, /* TX_LINK */ - (zil_replay_func_t *)zvol_replay_err, /* TX_RENAME */ - (zil_replay_func_t *)zvol_replay_write, /* TX_WRITE */ - (zil_replay_func_t *)zvol_replay_err, /* TX_TRUNCATE */ - (zil_replay_func_t *)zvol_replay_err, /* TX_SETATTR */ - (zil_replay_func_t *)zvol_replay_err, /* TX_ACL */ +zil_replay_func_t zvol_replay_vector[TX_MAX_TYPE] = { + (zil_replay_func_t)zvol_replay_err, /* no such transaction type */ + (zil_replay_func_t)zvol_replay_err, /* TX_CREATE */ + (zil_replay_func_t)zvol_replay_err, /* TX_MKDIR */ + (zil_replay_func_t)zvol_replay_err, /* TX_MKXATTR */ + (zil_replay_func_t)zvol_replay_err, /* TX_SYMLINK */ + (zil_replay_func_t)zvol_replay_err, /* TX_REMOVE */ + (zil_replay_func_t)zvol_replay_err, /* TX_RMDIR */ + (zil_replay_func_t)zvol_replay_err, /* TX_LINK */ + (zil_replay_func_t)zvol_replay_err, /* TX_RENAME */ + (zil_replay_func_t)zvol_replay_write, /* TX_WRITE */ + (zil_replay_func_t)zvol_replay_err, /* TX_TRUNCATE */ + (zil_replay_func_t)zvol_replay_err, /* TX_SETATTR */ + (zil_replay_func_t)zvol_replay_err, /* TX_ACL */ }; /*