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

Configure Feed

Select the types of activity you want to include in your feed.

sysctl: Create unsigned int converter using new macro

Pass sysctl_{user_to_kern,kern_to_user}_uint_conv (unsigned integer
uni-directional converters) to the new SYSCTL_UINT_CONV_CUSTOM macro
to create do_proc_douintvec_conv's replacement (do_proc_uint_conv).

This is a preparation commit to use the unsigned integer converter from
outside sysctl. No functional change is intended.

Signed-off-by: Joel Granados <joel.granados@kernel.org>

+28 -15
+28 -15
kernel/sysctl.c
··· 462 462 sysctl_user_to_kern_int_conv_ms, 463 463 sysctl_kern_to_user_int_conv_ms, true) 464 464 465 - static int do_proc_douintvec_conv(unsigned long *u_ptr, 466 - unsigned int *k_ptr, int dir, 467 - const struct ctl_table *table) 465 + #define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user) \ 466 + int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \ 467 + int dir, const struct ctl_table *tbl) \ 468 + { \ 469 + if (SYSCTL_USER_TO_KERN(dir)) \ 470 + return user_to_kern(u_ptr, k_ptr); \ 471 + return kern_to_user(u_ptr, k_ptr); \ 472 + } 473 + 474 + static int sysctl_user_to_kern_uint_conv(const unsigned long *u_ptr, 475 + unsigned int *k_ptr) 468 476 { 469 - if (SYSCTL_USER_TO_KERN(dir)) { 470 - if (*u_ptr > UINT_MAX) 471 - return -EINVAL; 472 - WRITE_ONCE(*k_ptr, *u_ptr); 473 - } else { 474 - unsigned int val = READ_ONCE(*k_ptr); 475 - *u_ptr = (unsigned long)val; 476 - } 477 + if (*u_ptr > UINT_MAX) 478 + return -EINVAL; 479 + WRITE_ONCE(*k_ptr, *u_ptr); 477 480 return 0; 478 481 } 479 482 480 - static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; 483 + static int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, 484 + const unsigned int *k_ptr) 485 + { 486 + unsigned int val = READ_ONCE(*k_ptr); 487 + *u_ptr = (unsigned long)val; 488 + return 0; 489 + } 481 490 491 + static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv, 492 + sysctl_kern_to_user_uint_conv) 493 + 494 + static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; 482 495 483 496 static int do_proc_dointvec(const struct ctl_table *table, int dir, 484 497 void *buffer, size_t *lenp, loff_t *ppos, ··· 673 660 } 674 661 675 662 if (!conv) 676 - conv = do_proc_douintvec_conv; 663 + conv = do_proc_uint_conv; 677 664 678 665 if (SYSCTL_USER_TO_KERN(dir)) 679 666 return do_proc_douintvec_w(table, buffer, lenp, ppos, conv); ··· 756 743 size_t *lenp, loff_t *ppos) 757 744 { 758 745 return do_proc_douintvec(table, dir, buffer, lenp, ppos, 759 - do_proc_douintvec_conv); 746 + do_proc_uint_conv); 760 747 } 761 748 762 749 /** ··· 792 779 /* When writing to the kernel use a temp local uint for bounds-checking */ 793 780 unsigned int *up = SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; 794 781 795 - ret = do_proc_douintvec_conv(u_ptr, up, dir, table); 782 + ret = do_proc_uint_conv(u_ptr, up, dir, table); 796 783 if (ret) 797 784 return ret; 798 785