w1: therm: Fix off-by-one buffer overflow in alarms_store

The sysfs buffer passed to alarms_store() is allocated with 'size + 1'
bytes and a NUL terminator is appended. However, the 'size' argument
does not account for this extra byte. The original code then allocated
'size' bytes and used strcpy() to copy 'buf', which always writes one
byte past the allocated buffer since strcpy() copies until the NUL
terminator at index 'size'.

Fix this by parsing the 'buf' parameter directly using simple_strtoll()
without allocating any intermediate memory or string copying. This
removes the overflow while simplifying the code.

Cc: stable@vger.kernel.org
Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20251216145007.44328-2-thorsten.blum@linux.dev
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>

authored by Thorsten Blum and committed by Krzysztof Kozlowski 761fcf46 8f0b4cce

+19 -41
+19 -41
drivers/w1/slaves/w1_therm.c
··· 1836 struct w1_slave *sl = dev_to_w1_slave(device); 1837 struct therm_info info; 1838 u8 new_config_register[3]; /* array of data to be written */ 1839 - int temp, ret; 1840 - char *token = NULL; 1841 s8 tl, th; /* 1 byte per value + temp ring order */ 1842 - char *p_args, *orig; 1843 1844 - p_args = orig = kmalloc(size, GFP_KERNEL); 1845 - /* Safe string copys as buf is const */ 1846 - if (!p_args) { 1847 - dev_warn(device, 1848 - "%s: error unable to allocate memory %d\n", 1849 - __func__, -ENOMEM); 1850 - return size; 1851 - } 1852 - strcpy(p_args, buf); 1853 - 1854 - /* Split string using space char */ 1855 - token = strsep(&p_args, " "); 1856 - 1857 - if (!token) { 1858 - dev_info(device, 1859 - "%s: error parsing args %d\n", __func__, -EINVAL); 1860 - goto free_m; 1861 - } 1862 - 1863 - /* Convert 1st entry to int */ 1864 - ret = kstrtoint (token, 10, &temp); 1865 if (ret) { 1866 dev_info(device, 1867 "%s: error parsing args %d\n", __func__, ret); 1868 - goto free_m; 1869 } 1870 1871 tl = int_to_short(temp); 1872 1873 - /* Split string using space char */ 1874 - token = strsep(&p_args, " "); 1875 - if (!token) { 1876 - dev_info(device, 1877 - "%s: error parsing args %d\n", __func__, -EINVAL); 1878 - goto free_m; 1879 - } 1880 - /* Convert 2nd entry to int */ 1881 - ret = kstrtoint (token, 10, &temp); 1882 if (ret) { 1883 dev_info(device, 1884 "%s: error parsing args %d\n", __func__, ret); 1885 - goto free_m; 1886 } 1887 1888 /* Prepare to cast to short by eliminating out of range values */ ··· 1887 dev_info(device, 1888 "%s: error reading from the slave device %d\n", 1889 __func__, ret); 1890 - goto free_m; 1891 } 1892 1893 /* Write data in the device RAM */ ··· 1895 dev_info(device, 1896 "%s: Device not supported by the driver %d\n", 1897 __func__, -ENODEV); 1898 - goto free_m; 1899 } 1900 1901 ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); ··· 1903 dev_info(device, 1904 "%s: error writing to the slave device %d\n", 1905 __func__, ret); 1906 - 1907 - free_m: 1908 - /* free allocated memory */ 1909 - kfree(orig); 1910 1911 return size; 1912 }
··· 1836 struct w1_slave *sl = dev_to_w1_slave(device); 1837 struct therm_info info; 1838 u8 new_config_register[3]; /* array of data to be written */ 1839 + long long temp; 1840 + int ret = 0; 1841 s8 tl, th; /* 1 byte per value + temp ring order */ 1842 + const char *p = buf; 1843 + char *endp; 1844 1845 + temp = simple_strtoll(p, &endp, 10); 1846 + if (p == endp || *endp != ' ') 1847 + ret = -EINVAL; 1848 + else if (temp < INT_MIN || temp > INT_MAX) 1849 + ret = -ERANGE; 1850 if (ret) { 1851 dev_info(device, 1852 "%s: error parsing args %d\n", __func__, ret); 1853 + return size; 1854 } 1855 1856 tl = int_to_short(temp); 1857 1858 + p = endp + 1; 1859 + temp = simple_strtoll(p, &endp, 10); 1860 + if (p == endp) 1861 + ret = -EINVAL; 1862 + else if (temp < INT_MIN || temp > INT_MAX) 1863 + ret = -ERANGE; 1864 if (ret) { 1865 dev_info(device, 1866 "%s: error parsing args %d\n", __func__, ret); 1867 + return size; 1868 } 1869 1870 /* Prepare to cast to short by eliminating out of range values */ ··· 1905 dev_info(device, 1906 "%s: error reading from the slave device %d\n", 1907 __func__, ret); 1908 + return size; 1909 } 1910 1911 /* Write data in the device RAM */ ··· 1913 dev_info(device, 1914 "%s: Device not supported by the driver %d\n", 1915 __func__, -ENODEV); 1916 + return size; 1917 } 1918 1919 ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); ··· 1921 dev_info(device, 1922 "%s: error writing to the slave device %d\n", 1923 __func__, ret); 1924 1925 return size; 1926 }