Re: [PATCH 01/11] params: bound array element output to the caller's page buffer
David Laight <[email protected]> Tue, 2 Jun 2026 14:04:51 +0100
| Newsgroups | org.infradead.lists.linux-um,dev.linux.lists.virtualization,org.freedesktop.lists.dri-devel,org.freedesktop.lists.intel-gfx,org.kernel.vger.dmaengine,org.kernel.vger.kvm,org.kernel.vger.linux-acpi,org.kernel.vger.linux-arch,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media,org.kernel.vger.linux-modules,org.kernel.vger.linux-pci,org.kernel.vger.linux-pm,org.kernel.vger.linux-rdma,org.kernel.vger.linux-scsi,org.kernel.vger.linux-security-module,org.kernel.vger.linux-serial,org.kernel.vger.linux-usb,org.kernel.vger.netdev,org.kernel.vger.stable,org.kvack.linux-mm,org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <20260602140451.2e3e6622@pumpkin> |
On Tue, 2 Jun 2026 14:26:46 +0300 Andy Shevchenko <[email protected]> wrote: > On Thu, May 21, 2026 at 06:33:14AM -0700, Kees Cook wrote: > > > > param_array_get() appends each element's string representation into the > > shared sysfs page buffer by passing buffer + off to the element getter. > > > > That works for getters that only write a small bounded string, but > > param_get_charp() and similar helpers format against PAGE_SIZE from the > > pointer they receive. Once off is non-zero, an element getter can > > therefore write past the end of the original sysfs page buffer. > > > > Collect each element into a temporary PAGE_SIZE buffer first and then > > copy only the remaining space into the caller's page buffer. > > ... > > > + elem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); > > get_free_page() (or how it is called)? The kmalloc() should be faster and I think has to be aligned. There is another patch set to replace get_free_pages() with kmalloc(). Although all these 'show' functions should really head to using a safer interface. Although, at the moment, it is really difficult to find the ones that are guaranteed to be passed a page aligned buffer. -- David > > > + if (!elem_buf) > > + return -ENOMEM; > > + > > for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) { > > - /* Replace \n with comma */ > > - if (i) > > - buffer[off - 1] = ','; > > p.arg = arr->elem + arr->elemsize * i; > > check_kparam_locked(p.mod); > > - ret = arr->ops->get(buffer + off, &p); > > + ret = arr->ops->get(elem_buf, &p); > > if (ret < 0) > > - return ret; > > + goto out; > > + ret = min(ret, (int)(PAGE_SIZE - 1 - off)); > > It's usually discouraged to use castings in min/max/clamp. Can we make ret long > or do something different here? > > > + if (!ret) > > + break; > > > + /* Replace the previous element's trailing newline with a comma. */ > > + if (i) > > + buffer[off - 1] = ','; > > Can't we do this after with help of strreplace()? > > > + memcpy(buffer + off, elem_buf, ret); > > off += ret; > > + if (off == PAGE_SIZE - 1) > > + break; > > } > > buffer[off] = '\0'; > > - return off; > > + ret = off; > > +out: > > + kfree(elem_buf); > > + return ret; >