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.

tty/vt: use guard()s in con_font_set/get() and con_{set,get}_unimap()

Having all the new guards, use them in the 8250_rsa code. This improves
readability, makes error handling easier, and marks locked portions of
code explicit.

The new __free()-annotated declarations are moved to the allocation points
as is preferred:
https://lore.kernel.org/all/CAHk-=wjvh_LUpa=864joG2JJXs3+viO-kLzLidR2JLyMr4MNwA@mail.gmail.com/

Except font_data in con_font_get(). The scope in there would not match
the expected lifetime. But the declaration is moved closer.

Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20250814072456.182853-15-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jiri Slaby (SUSE) and committed by
Greg Kroah-Hartman
2fe16088 54faf047

+78 -95
+38 -46
drivers/tty/vt/consolemap.c
··· 637 637 638 638 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) 639 639 { 640 - int err = 0, err1; 641 640 struct uni_pagedict *dict; 642 - struct unipair *unilist, *plist; 641 + struct unipair *plist; 642 + int err = 0; 643 643 644 644 if (!ct) 645 645 return 0; 646 646 647 - unilist = vmemdup_array_user(list, ct, sizeof(*unilist)); 647 + struct unipair *unilist __free(kvfree) = vmemdup_array_user(list, ct, sizeof(*unilist)); 648 648 if (IS_ERR(unilist)) 649 649 return PTR_ERR(unilist); 650 650 651 - console_lock(); 651 + guard(console_lock)(); 652 652 653 653 /* Save original vc_unipagdir_loc in case we allocate a new one */ 654 654 dict = *vc->uni_pagedict_loc; 655 - if (!dict) { 656 - err = -EINVAL; 657 - goto out_unlock; 658 - } 655 + if (!dict) 656 + return -EINVAL; 659 657 660 658 if (dict->refcount > 1) { 661 659 dict = con_unshare_unimap(vc, dict); 662 - if (IS_ERR(dict)) { 663 - err = PTR_ERR(dict); 664 - goto out_unlock; 665 - } 660 + if (IS_ERR(dict)) 661 + return PTR_ERR(dict); 666 662 } else if (dict == dflt) { 667 663 dflt = NULL; 668 664 } ··· 667 671 * Insert user specified unicode pairs into new table. 668 672 */ 669 673 for (plist = unilist; ct; ct--, plist++) { 670 - err1 = con_insert_unipair(dict, plist->unicode, plist->fontpos); 674 + int err1 = con_insert_unipair(dict, plist->unicode, plist->fontpos); 671 675 if (err1) 672 676 err = err1; 673 677 } ··· 676 680 * Merge with fontmaps of any other virtual consoles. 677 681 */ 678 682 if (con_unify_unimap(vc, dict)) 679 - goto out_unlock; 683 + return err; 680 684 681 685 for (enum translation_map m = FIRST_MAP; m <= LAST_MAP; m++) 682 686 set_inverse_transl(vc, dict, m); 683 687 set_inverse_trans_unicode(dict); 684 688 685 - out_unlock: 686 - console_unlock(); 687 - kvfree(unilist); 688 689 return err; 689 690 } 690 691 ··· 780 787 { 781 788 ushort ect; 782 789 struct uni_pagedict *dict; 783 - struct unipair *unilist; 784 790 unsigned int d, r, g; 785 - int ret = 0; 786 791 787 - unilist = kvmalloc_array(ct, sizeof(*unilist), GFP_KERNEL); 792 + struct unipair *unilist __free(kvfree) = kvmalloc_array(ct, sizeof(*unilist), GFP_KERNEL); 788 793 if (!unilist) 789 794 return -ENOMEM; 790 795 791 - console_lock(); 796 + scoped_guard(console_lock) { 797 + ect = 0; 798 + dict = *vc->uni_pagedict_loc; 799 + if (!dict) 800 + break; 792 801 793 - ect = 0; 794 - dict = *vc->uni_pagedict_loc; 795 - if (!dict) 796 - goto unlock; 797 - 798 - for (d = 0; d < UNI_DIRS; d++) { 799 - u16 **dir = dict->uni_pgdir[d]; 800 - if (!dir) 801 - continue; 802 - 803 - for (r = 0; r < UNI_DIR_ROWS; r++) { 804 - u16 *row = dir[r]; 805 - if (!row) 802 + for (d = 0; d < UNI_DIRS; d++) { 803 + u16 **dir = dict->uni_pgdir[d]; 804 + if (!dir) 806 805 continue; 807 806 808 - for (g = 0; g < UNI_ROW_GLYPHS; g++, row++) { 809 - if (*row >= MAX_GLYPH) 807 + for (r = 0; r < UNI_DIR_ROWS; r++) { 808 + u16 *row = dir[r]; 809 + if (!row) 810 810 continue; 811 - if (ect < ct) { 812 - unilist[ect].unicode = UNI(d, r, g); 813 - unilist[ect].fontpos = *row; 811 + 812 + for (g = 0; g < UNI_ROW_GLYPHS; g++, row++) { 813 + if (*row >= MAX_GLYPH) 814 + continue; 815 + if (ect < ct) { 816 + unilist[ect].unicode = UNI(d, r, g); 817 + unilist[ect].fontpos = *row; 818 + } 819 + ect++; 814 820 } 815 - ect++; 816 821 } 817 822 } 818 823 } 819 - unlock: 820 - console_unlock(); 824 + 821 825 if (copy_to_user(list, unilist, min(ect, ct) * sizeof(*unilist))) 822 - ret = -EFAULT; 826 + return -EFAULT; 823 827 if (put_user(ect, uct)) 824 - ret = -EFAULT; 825 - kvfree(unilist); 826 - return ret ? ret : (ect <= ct) ? 0 : -ENOMEM; 828 + return -EFAULT; 829 + if (ect > ct) 830 + return -ENOMEM; 831 + 832 + return 0; 827 833 } 828 834 829 835 /*
+40 -49
drivers/tty/vt/vt.c
··· 4801 4801 static int con_font_get(struct vc_data *vc, struct console_font_op *op) 4802 4802 { 4803 4803 struct console_font font; 4804 - int rc = -EINVAL; 4805 4804 int c; 4806 4805 unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; 4807 4806 4808 4807 if (vpitch > max_font_height) 4809 4808 return -EINVAL; 4810 4809 4810 + void *font_data __free(kvfree) = NULL; 4811 4811 if (op->data) { 4812 - font.data = kvzalloc(max_font_size, GFP_KERNEL); 4812 + font.data = font_data = kvzalloc(max_font_size, GFP_KERNEL); 4813 4813 if (!font.data) 4814 4814 return -ENOMEM; 4815 4815 } else 4816 4816 font.data = NULL; 4817 4817 4818 - console_lock(); 4819 - if (vc->vc_mode != KD_TEXT) 4820 - rc = -EINVAL; 4821 - else if (vc->vc_sw->con_font_get) 4822 - rc = vc->vc_sw->con_font_get(vc, &font, vpitch); 4823 - else 4824 - rc = -ENOSYS; 4825 - console_unlock(); 4818 + scoped_guard(console_lock) { 4819 + if (vc->vc_mode != KD_TEXT) 4820 + return -EINVAL; 4821 + if (!vc->vc_sw->con_font_get) 4822 + return -ENOSYS; 4826 4823 4827 - if (rc) 4828 - goto out; 4824 + int ret = vc->vc_sw->con_font_get(vc, &font, vpitch); 4825 + if (ret) 4826 + return ret; 4827 + } 4829 4828 4830 4829 c = (font.width+7)/8 * vpitch * font.charcount; 4831 4830 4832 4831 if (op->data && font.charcount > op->charcount) 4833 - rc = -ENOSPC; 4832 + return -ENOSPC; 4834 4833 if (font.width > op->width || font.height > op->height) 4835 - rc = -ENOSPC; 4836 - if (rc) 4837 - goto out; 4834 + return -ENOSPC; 4838 4835 4839 4836 op->height = font.height; 4840 4837 op->width = font.width; 4841 4838 op->charcount = font.charcount; 4842 4839 4843 4840 if (op->data && copy_to_user(op->data, font.data, c)) 4844 - rc = -EFAULT; 4841 + return -EFAULT; 4845 4842 4846 - out: 4847 - kvfree(font.data); 4848 - return rc; 4843 + return 0; 4849 4844 } 4850 4845 4851 4846 static int con_font_set(struct vc_data *vc, const struct console_font_op *op) 4852 4847 { 4853 4848 struct console_font font; 4854 - int rc = -EINVAL; 4855 4849 int size; 4856 4850 unsigned int vpitch = op->op == KD_FONT_OP_SET_TALL ? op->height : 32; 4857 4851 ··· 4864 4870 if (size > max_font_size) 4865 4871 return -ENOSPC; 4866 4872 4867 - font.data = memdup_user(op->data, size); 4873 + void *font_data __free(kfree) = font.data = memdup_user(op->data, size); 4868 4874 if (IS_ERR(font.data)) 4869 4875 return PTR_ERR(font.data); 4870 4876 ··· 4872 4878 font.width = op->width; 4873 4879 font.height = op->height; 4874 4880 4875 - console_lock(); 4881 + guard(console_lock)(); 4882 + 4876 4883 if (vc->vc_mode != KD_TEXT) 4877 - rc = -EINVAL; 4878 - else if (vc->vc_sw->con_font_set) { 4879 - if (vc_is_sel(vc)) 4880 - clear_selection(); 4881 - rc = vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags); 4882 - } else 4883 - rc = -ENOSYS; 4884 - console_unlock(); 4885 - kfree(font.data); 4886 - return rc; 4884 + return -EINVAL; 4885 + if (!vc->vc_sw->con_font_set) 4886 + return -ENOSYS; 4887 + 4888 + if (vc_is_sel(vc)) 4889 + clear_selection(); 4890 + 4891 + return vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags); 4887 4892 } 4888 4893 4889 4894 static int con_font_default(struct vc_data *vc, struct console_font_op *op) ··· 4890 4897 struct console_font font = {.width = op->width, .height = op->height}; 4891 4898 char name[MAX_FONT_NAME]; 4892 4899 char *s = name; 4893 - int rc; 4894 - 4895 4900 4896 4901 if (!op->data) 4897 4902 s = NULL; ··· 4898 4907 else 4899 4908 name[MAX_FONT_NAME - 1] = 0; 4900 4909 4901 - console_lock(); 4902 - if (vc->vc_mode != KD_TEXT) { 4903 - console_unlock(); 4904 - return -EINVAL; 4905 - } 4906 - if (vc->vc_sw->con_font_default) { 4910 + scoped_guard(console_lock) { 4911 + if (vc->vc_mode != KD_TEXT) 4912 + return -EINVAL; 4913 + if (!vc->vc_sw->con_font_default) 4914 + return -ENOSYS; 4915 + 4907 4916 if (vc_is_sel(vc)) 4908 4917 clear_selection(); 4909 - rc = vc->vc_sw->con_font_default(vc, &font, s); 4910 - } else 4911 - rc = -ENOSYS; 4912 - console_unlock(); 4913 - if (!rc) { 4914 - op->width = font.width; 4915 - op->height = font.height; 4918 + int ret = vc->vc_sw->con_font_default(vc, &font, s); 4919 + if (ret) 4920 + return ret; 4916 4921 } 4917 - return rc; 4922 + 4923 + op->width = font.width; 4924 + op->height = font.height; 4925 + 4926 + return 0; 4918 4927 } 4919 4928 4920 4929 int con_font_op(struct vc_data *vc, struct console_font_op *op)