Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sunrpc: Const-ify struct sv_serv_ops

Close an attack vector by moving the arrays of per-server methods to
read-only memory.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Chuck Lever and committed by
J. Bruce Fields
afea5657 c1df609d

+13 -13
+1 -1
fs/lockd/svc.c
··· 396 396 return error; 397 397 } 398 398 399 - static struct svc_serv_ops lockd_sv_ops = { 399 + static const struct svc_serv_ops lockd_sv_ops = { 400 400 .svo_shutdown = svc_rpcb_cleanup, 401 401 .svo_enqueue_xprt = svc_xprt_do_enqueue, 402 402 };
+5 -5
fs/nfs/callback.c
··· 226 226 return ret; 227 227 } 228 228 229 - static struct svc_serv_ops nfs40_cb_sv_ops = { 229 + static const struct svc_serv_ops nfs40_cb_sv_ops = { 230 230 .svo_function = nfs4_callback_svc, 231 231 .svo_enqueue_xprt = svc_xprt_do_enqueue, 232 232 .svo_setup = svc_set_num_threads_sync, 233 233 .svo_module = THIS_MODULE, 234 234 }; 235 235 #if defined(CONFIG_NFS_V4_1) 236 - static struct svc_serv_ops nfs41_cb_sv_ops = { 236 + static const struct svc_serv_ops nfs41_cb_sv_ops = { 237 237 .svo_function = nfs41_callback_svc, 238 238 .svo_enqueue_xprt = svc_xprt_do_enqueue, 239 239 .svo_setup = svc_set_num_threads_sync, 240 240 .svo_module = THIS_MODULE, 241 241 }; 242 242 243 - static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 243 + static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { 244 244 [0] = &nfs40_cb_sv_ops, 245 245 [1] = &nfs41_cb_sv_ops, 246 246 }; 247 247 #else 248 - static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 248 + static const struct svc_serv_ops *nfs4_cb_sv_ops[] = { 249 249 [0] = &nfs40_cb_sv_ops, 250 250 [1] = NULL, 251 251 }; ··· 254 254 static struct svc_serv *nfs_callback_create_svc(int minorversion) 255 255 { 256 256 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 257 + const struct svc_serv_ops *sv_ops; 257 258 struct svc_serv *serv; 258 - struct svc_serv_ops *sv_ops; 259 259 260 260 /* 261 261 * Check whether we're already up and running.
+1 -1
fs/nfsd/nfssvc.c
··· 475 475 return ret; 476 476 } 477 477 478 - static struct svc_serv_ops nfsd_thread_sv_ops = { 478 + static const struct svc_serv_ops nfsd_thread_sv_ops = { 479 479 .svo_shutdown = nfsd_last_thread, 480 480 .svo_function = nfsd, 481 481 .svo_enqueue_xprt = svc_xprt_do_enqueue,
+3 -3
include/linux/sunrpc/svc.h
··· 99 99 100 100 unsigned int sv_nrpools; /* number of thread pools */ 101 101 struct svc_pool * sv_pools; /* array of thread pools */ 102 - struct svc_serv_ops *sv_ops; /* server operations */ 102 + const struct svc_serv_ops *sv_ops; /* server operations */ 103 103 #if defined(CONFIG_SUNRPC_BACKCHANNEL) 104 104 struct list_head sv_cb_list; /* queue for callback requests 105 105 * that arrive over the same ··· 465 465 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 466 466 int svc_bind(struct svc_serv *serv, struct net *net); 467 467 struct svc_serv *svc_create(struct svc_program *, unsigned int, 468 - struct svc_serv_ops *); 468 + const struct svc_serv_ops *); 469 469 struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv, 470 470 struct svc_pool *pool, int node); 471 471 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, ··· 475 475 unsigned int svc_pool_map_get(void); 476 476 void svc_pool_map_put(void); 477 477 struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, 478 - struct svc_serv_ops *); 478 + const struct svc_serv_ops *); 479 479 int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); 480 480 int svc_set_num_threads_sync(struct svc_serv *, struct svc_pool *, int); 481 481 int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
+3 -3
net/sunrpc/svc.c
··· 421 421 */ 422 422 static struct svc_serv * 423 423 __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, 424 - struct svc_serv_ops *ops) 424 + const struct svc_serv_ops *ops) 425 425 { 426 426 struct svc_serv *serv; 427 427 unsigned int vers; ··· 486 486 487 487 struct svc_serv * 488 488 svc_create(struct svc_program *prog, unsigned int bufsize, 489 - struct svc_serv_ops *ops) 489 + const struct svc_serv_ops *ops) 490 490 { 491 491 return __svc_create(prog, bufsize, /*npools*/1, ops); 492 492 } ··· 494 494 495 495 struct svc_serv * 496 496 svc_create_pooled(struct svc_program *prog, unsigned int bufsize, 497 - struct svc_serv_ops *ops) 497 + const struct svc_serv_ops *ops) 498 498 { 499 499 struct svc_serv *serv; 500 500 unsigned int npools = svc_pool_map_get();