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/keyboard: use __free()

The vt/keyboard code can use __free to ensure the temporary buffers are
freed. Perform the switch.

And even one non-temporary in kbd_connect(). There are fail paths, so
ensure the buffer is freed in them and not when returning 0 -- by
retain_and_null_ptr().

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://patch.msgid.link/20251119100140.830761-7-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jiri Slaby (SUSE) and committed by
Greg Kroah-Hartman
bfb24564 1c7736dc

+37 -53
+37 -53
drivers/tty/vt/keyboard.c
··· 1566 1566 static int kbd_connect(struct input_handler *handler, struct input_dev *dev, 1567 1567 const struct input_device_id *id) 1568 1568 { 1569 - struct input_handle *handle; 1570 1569 int error; 1571 1570 1572 - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); 1571 + struct input_handle __free(kfree) *handle = kzalloc(sizeof(*handle), GFP_KERNEL); 1573 1572 if (!handle) 1574 1573 return -ENOMEM; 1575 1574 ··· 1578 1579 1579 1580 error = input_register_handle(handle); 1580 1581 if (error) 1581 - goto err_free_handle; 1582 + return error; 1582 1583 1583 1584 error = input_open_device(handle); 1584 1585 if (error) 1585 1586 goto err_unregister_handle; 1586 1587 1588 + retain_and_null_ptr(handle); 1589 + 1587 1590 return 0; 1588 1591 1589 1592 err_unregister_handle: 1590 1593 input_unregister_handle(handle); 1591 - err_free_handle: 1592 - kfree(handle); 1593 1594 return error; 1594 1595 } 1595 1596 ··· 1682 1683 { 1683 1684 unsigned long flags; 1684 1685 int asize; 1685 - int ret = 0; 1686 1686 1687 1687 switch (cmd) { 1688 1688 case KDGKBDIACR: 1689 1689 { 1690 1690 struct kbdiacrs __user *a = udp; 1691 - struct kbdiacr *dia; 1692 1691 int i; 1693 1692 1694 - dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr), 1695 - GFP_KERNEL); 1693 + struct kbdiacr __free(kfree) *dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr), 1694 + GFP_KERNEL); 1696 1695 if (!dia) 1697 1696 return -ENOMEM; 1698 1697 ··· 1710 1713 spin_unlock_irqrestore(&kbd_event_lock, flags); 1711 1714 1712 1715 if (put_user(asize, &a->kb_cnt)) 1713 - ret = -EFAULT; 1714 - else if (copy_to_user(a->kbdiacr, dia, 1715 - asize * sizeof(struct kbdiacr))) 1716 - ret = -EFAULT; 1717 - kfree(dia); 1718 - return ret; 1716 + return -EFAULT; 1717 + if (copy_to_user(a->kbdiacr, dia, asize * sizeof(struct kbdiacr))) 1718 + return -EFAULT; 1719 + return 0; 1719 1720 } 1720 1721 case KDGKBDIACRUC: 1721 1722 { 1722 1723 struct kbdiacrsuc __user *a = udp; 1723 - void *buf; 1724 1724 1725 - buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc), 1726 - GFP_KERNEL); 1725 + void __free(kfree) *buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc), 1726 + GFP_KERNEL); 1727 1727 if (buf == NULL) 1728 1728 return -ENOMEM; 1729 1729 ··· 1734 1740 spin_unlock_irqrestore(&kbd_event_lock, flags); 1735 1741 1736 1742 if (put_user(asize, &a->kb_cnt)) 1737 - ret = -EFAULT; 1738 - else if (copy_to_user(a->kbdiacruc, buf, 1739 - asize*sizeof(struct kbdiacruc))) 1740 - ret = -EFAULT; 1741 - kfree(buf); 1742 - return ret; 1743 + return -EFAULT; 1744 + if (copy_to_user(a->kbdiacruc, buf, asize * sizeof(struct kbdiacruc))) 1745 + return -EFAULT; 1746 + 1747 + return 0; 1743 1748 } 1744 1749 1745 1750 case KDSKBDIACR: 1746 1751 { 1747 1752 struct kbdiacrs __user *a = udp; 1748 - struct kbdiacr *dia = NULL; 1753 + struct kbdiacr __free(kfree) *dia = NULL; 1749 1754 unsigned int ct; 1750 1755 int i; 1751 1756 ··· 1773 1780 conv_8bit_to_uni(dia[i].result); 1774 1781 } 1775 1782 spin_unlock_irqrestore(&kbd_event_lock, flags); 1776 - kfree(dia); 1783 + 1777 1784 return 0; 1778 1785 } 1779 1786 ··· 1781 1788 { 1782 1789 struct kbdiacrsuc __user *a = udp; 1783 1790 unsigned int ct; 1784 - void *buf = NULL; 1791 + void __free(kfree) *buf = NULL; 1785 1792 1786 1793 if (!perm) 1787 1794 return -EPERM; ··· 1804 1811 ct * sizeof(struct kbdiacruc)); 1805 1812 accent_table_size = ct; 1806 1813 spin_unlock_irqrestore(&kbd_event_lock, flags); 1807 - kfree(buf); 1808 1814 return 0; 1809 1815 } 1810 1816 } 1811 - return ret; 1817 + return 0; 1812 1818 } 1813 1819 1814 1820 /** ··· 1926 1934 unsigned char map, unsigned short val) 1927 1935 { 1928 1936 unsigned long flags; 1929 - unsigned short *key_map, *new_map, oldval; 1937 + unsigned short *key_map, oldval; 1930 1938 1931 1939 if (!idx && val == K_NOSUCHMAP) { 1932 1940 spin_lock_irqsave(&kbd_event_lock, flags); ··· 1957 1965 return 0; 1958 1966 #endif 1959 1967 1960 - new_map = kmalloc(sizeof(plain_map), GFP_KERNEL); 1968 + unsigned short __free(kfree) *new_map = kmalloc(sizeof(plain_map), GFP_KERNEL); 1961 1969 if (!new_map) 1962 1970 return -ENOMEM; 1963 1971 ··· 1969 1977 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && 1970 1978 !capable(CAP_SYS_RESOURCE)) { 1971 1979 spin_unlock_irqrestore(&kbd_event_lock, flags); 1972 - kfree(new_map); 1973 1980 return -EPERM; 1974 1981 } 1975 - key_maps[map] = new_map; 1976 - key_map = new_map; 1982 + key_map = key_maps[map] = no_free_ptr(new_map); 1977 1983 key_map[0] = U(K_ALLOCATED); 1978 1984 for (j = 1; j < NR_KEYS; j++) 1979 1985 key_map[j] = U(K_HOLE); 1980 1986 keymap_count++; 1981 - } else 1982 - kfree(new_map); 1987 + } 1983 1988 1984 1989 oldval = U(key_map[idx]); 1985 1990 if (val == oldval) ··· 2039 2050 { 2040 2051 unsigned char kb_func; 2041 2052 unsigned long flags; 2042 - char *kbs; 2043 - int ret; 2044 2053 2045 2054 if (get_user(kb_func, &user_kdgkb->kb_func)) 2046 2055 return -EFAULT; ··· 2050 2063 /* size should have been a struct member */ 2051 2064 ssize_t len = sizeof(user_kdgkb->kb_string); 2052 2065 2053 - kbs = kmalloc(len, GFP_KERNEL); 2066 + char __free(kfree) *kbs = kmalloc(len, GFP_KERNEL); 2054 2067 if (!kbs) 2055 2068 return -ENOMEM; 2056 2069 ··· 2058 2071 len = strscpy(kbs, func_table[kb_func] ? : "", len); 2059 2072 spin_unlock_irqrestore(&func_buf_lock, flags); 2060 2073 2061 - if (len < 0) { 2062 - ret = -ENOSPC; 2063 - break; 2064 - } 2065 - ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ? 2066 - -EFAULT : 0; 2067 - break; 2074 + if (len < 0) 2075 + return -ENOSPC; 2076 + 2077 + if (copy_to_user(user_kdgkb->kb_string, kbs, len + 1)) 2078 + return -EFAULT; 2079 + 2080 + return 0; 2068 2081 } 2069 2082 case KDSKBSENT: 2070 2083 if (!perm || !capable(CAP_SYS_TTY_CONFIG)) 2071 2084 return -EPERM; 2072 2085 2073 - kbs = strndup_user(user_kdgkb->kb_string, 2074 - sizeof(user_kdgkb->kb_string)); 2086 + char __free(kfree) *kbs = strndup_user(user_kdgkb->kb_string, 2087 + sizeof(user_kdgkb->kb_string)); 2075 2088 if (IS_ERR(kbs)) 2076 2089 return PTR_ERR(kbs); 2077 2090 ··· 2079 2092 kbs = vt_kdskbsent(kbs, kb_func); 2080 2093 spin_unlock_irqrestore(&func_buf_lock, flags); 2081 2094 2082 - ret = 0; 2083 - break; 2095 + return 0; 2084 2096 } 2085 2097 2086 - kfree(kbs); 2087 - 2088 - return ret; 2098 + return 0; 2089 2099 } 2090 2100 2091 2101 int vt_do_kdskled(unsigned int console, int cmd, unsigned long arg, int perm)