[bug report] zram: unlock slot during recompression

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Sergey Senozhatsky,

Commit 7ec2cb65ef0d ("zram: unlock slot during recompression") from
Jan 27, 2025 (linux-next), leads to the following Smatch static
checker warning:

	drivers/block/zram/zram_drv.c:1960 recompress_slot()
	warn: passing freed memory 'zstrm' (line 1943)

drivers/block/zram/zram_drv.c
    1873 static int recompress_slot(struct zram *zram, u32 index, struct page *page,
    1874                            u64 *num_recomp_pages, u32 threshold, u32 prio,
    1875                            u32 prio_max)
    1876 {
    1877         struct zcomp_strm *zstrm = NULL;
    1878         unsigned long handle_old;
    1879         unsigned long handle_new;
    1880         unsigned int comp_len_old;
    1881         unsigned int comp_len_new;
    1882         unsigned int class_index_old;
    1883         unsigned int class_index_new;
    1884         u32 num_recomps = 0;
    1885         void *src, *dst;
    1886         int ret;
    1887 
    1888         handle_old = zram_get_handle(zram, index);
    1889         if (!handle_old)
    1890                 return -EINVAL;
    1891 
    1892         comp_len_old = zram_get_obj_size(zram, index);
    1893         /*
    1894          * Do not recompress objects that are already "small enough".
    1895          */
    1896         if (comp_len_old < threshold)
    1897                 return 0;
    1898 
    1899         ret = zram_read_from_zspool(zram, page, index);
    1900         if (ret)
    1901                 return ret;
    1902 
    1903         /*
    1904          * We touched this entry so mark it as non-IDLE. This makes sure that
    1905          * we don't preserve IDLE flag and don't incorrectly pick this entry
    1906          * for different post-processing type (e.g. writeback).
    1907          */
    1908         zram_clear_flag(zram, index, ZRAM_IDLE);
    1909 
    1910         class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old);
    1911 
    1912         /*
    1913          * Set prio to one past current slot's compression prio, so that
    1914          * we automatically skip lower priority algorithms.
    1915          */
    1916         prio = zram_get_priority(zram, index) + 1;
    1917         /* Slot data copied out - unlock its bucket */
    1918         zram_slot_write_unlock(zram, index);
    1919         /*
    1920          * Iterate the secondary comp algorithms list (in order of priority)
    1921          * and try to recompress the page.
    1922          */
    1923         for (; prio < prio_max; prio++) {
    1924                 if (!zram->comps[prio])
    1925                         continue;
    1926 
    1927                 num_recomps++;
    1928                 zstrm = zcomp_stream_get(zram->comps[prio]);
    1929                 src = kmap_local_page(page);
    1930                 ret = zcomp_compress(zram->comps[prio], zstrm,
    1931                                      src, &comp_len_new);
    1932                 kunmap_local(src);
    1933 
    1934                 if (ret)
    1935                         break;
    1936 
    1937                 class_index_new = zs_lookup_class_index(zram->mem_pool,
    1938                                                         comp_len_new);
    1939 
    1940                 /* Continue until we make progress */
    1941                 if (class_index_new >= class_index_old ||
    1942                     (threshold && comp_len_new >= threshold)) {
    1943                         zcomp_stream_put(zram->comps[prio], zstrm);

Imagine we hit this continue path.  The right thing is probably to set
zstrm = NULL before the continue or it might be to set ret = -EINVAL.

    1944                         continue;
    1945                 }
    1946 
    1947                 /* Recompression was successful so break out */
    1948                 break;
    1949         }
    1950 
    1951         zram_slot_write_lock(zram, index);
    1952         /* Compression error */
    1953         if (ret) {
    1954                 zcomp_stream_put(zram->comps[prio], zstrm);
    1955                 return ret;
    1956         }
    1957 
    1958         /* Slot has been modified concurrently */
    1959         if (!zram_test_flag(zram, index, ZRAM_PP_SLOT)) {
--> 1960                 zcomp_stream_put(zram->comps[prio], zstrm);
                                                             ^^^^^
Use after free

    1961                 return 0;
    1962         }
    1963 
    1964         /*
    1965          * We did not try to recompress, e.g. when we have only one
    1966          * secondary algorithm and the page is already recompressed
    1967          * using that algorithm
    1968          */
    1969         if (!zstrm)
                      ^^^^^^
Could be a non-NULL freed pointer.

    1970                 return 0;

regards,
dan carpenter




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux