On Wed, 2020-10-07 at 09:53 -0300, Jason Gunthorpe wrote: > On Wed, Oct 07, 2020 at 12:16:01AM -0700, Kees Cook wrote: > > On Tue, Oct 06, 2020 at 09:28:17AM -0700, Joe Perches wrote: > > > Convert the various uses of sprintf/snprintf/scnprintf to > > > format sysfs output to sysfs_emit and sysfs_emit_at to make > > > clear the output is sysfs related and to avoid any possible > > > buffer overrun of the PAGE_SIZE buffer. > > > > > > Done with cocci scripts and some typing. > > > > Can you include the cocci script in the commit log? It might be nicer to > > split the "manual" changes from the cocci changes, as that makes review > > much easier too. > > > > Regardless, yes, I'm a fan of switching these all around to > > sysfs_emit*(). :) > > Yah, +1, I'd welcome patches for drivers/infiniband as well next cycle The script to change <foo>_show(struct device *, ...) function uses of sprintf to sysfs_emit is attached. The cocci script is coarse and doesn't find nor change all the possible variants of the sprintf uses in these functions. It could be run using: $ spatch --in-place -sp-file sysfs_emit.cocci drivers/infiniband/ Against next-20201007 it produces: $ git diff --shortstat drivers/infiniband 25 files changed, 322 insertions(+), 303 deletions(-) Because it touches a lot of drivers, the 'cc' list is pretty large for the diff. Given the size of the cc list, unless there's a single acceptable patch, I will not submit individual patches as I really dislike the back and forth of this sub-maintainer will but this sub-maintainer will not apply a patch. Doug Ledford <dledford@xxxxxxxxxx> (supporter:INFINIBAND SUBSYSTEM) Jason Gunthorpe <jgg@xxxxxxxx> (supporter:INFINIBAND SUBSYSTEM) Selvin Xavier <selvin.xavier@xxxxxxxxxxxx> (supporter:BROADCOM NETXTREME-E ROCE DRIVER) Devesh Sharma <devesh.sharma@xxxxxxxxxxxx> (supporter:BROADCOM NETXTREME-E ROCE DRIVER) Somnath Kotur <somnath.kotur@xxxxxxxxxxxx> (supporter:BROADCOM NETXTREME-E ROCE DRIVER) Sriharsha Basavapatna <sriharsha.basavapatna@xxxxxxxxxxxx> (supporter:BROADCOM NETXTREME-E ROCE DRIVER) Naresh Kumar PBS <nareshkumar.pbs@xxxxxxxxxxxx> (supporter:BROADCOM NETXTREME-E ROCE DRIVER) Potnuri Bharat Teja <bharat@xxxxxxxxxxx> (supporter:CXGB4 IWARP RNIC DRIVER (IW_CXGB4)) Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx> (supporter:HFI1 DRIVER) Dennis Dalessandro <dennis.dalessandro@xxxxxxxxx> (supporter:HFI1 DRIVER) Faisal Latif <faisal.latif@xxxxxxxxx> (supporter:INTEL RDMA RNIC DRIVER) Shiraz Saleem <shiraz.saleem@xxxxxxxxx> (supporter:INTEL RDMA RNIC DRIVER) Yishai Hadas <yishaih@xxxxxxxxxx> (supporter:MELLANOX MLX4 IB driver) Leon Romanovsky <leon@xxxxxxxxxx> (supporter:MELLANOX MLX5 IB driver) Michal Kalderon <mkalderon@xxxxxxxxxxx> (supporter:QLOGIC QL4xxx RDMA DRIVER) Ariel Elior <aelior@xxxxxxxxxxx> (supporter:QLOGIC QL4xxx RDMA DRIVER) Christian Benvenuti <benve@xxxxxxxxx> (supporter:CISCO VIC LOW LATENCY NIC DRIVER) Nelson Escobar <neescoba@xxxxxxxxx> (supporter:CISCO VIC LOW LATENCY NIC DRIVER) Parvi Kaustubhi <pkaustub@xxxxxxxxx> (supporter:CISCO VIC LOW LATENCY NIC DRIVER) Adit Ranadive <aditr@xxxxxxxxxx> (maintainer:VMWARE PVRDMA DRIVER) VMware PV-Drivers <pv-drivers@xxxxxxxxxx> (maintainer:VMWARE PVRDMA DRIVER) Zhu Yanjun <yanjunz@xxxxxxxxxx> (supporter:SOFT-ROCE DRIVER (rxe)) Danil Kipnis <danil.kipnis@xxxxxxxxxxxxxxx> (maintainer:RTRS TRANSPORT DRIVERS) Jack Wang <jinpu.wang@xxxxxxxxxxxxxxx> (maintainer:RTRS TRANSPORT DRIVERS) Bart Van Assche <bvanassche@xxxxxxx> (supporter:SCSI RDMA PROTOCOL (SRP) INITIATOR) linux-rdma@xxxxxxxxxxxxxxx (open list:INFINIBAND SUBSYSTEM) linux-kernel@xxxxxxxxxxxxxxx (open list)
@@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier arg1, arg2, arg3; @@ ssize_t d_show(struct device * - arg1 + dev , struct device_attribute * - arg2 + attr , char * - arg3 + buf ) { <... ( - arg1 + dev | - arg2 + attr | - arg3 + buf ) ...> } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... return - sprintf(buf, + sysfs_emit(buf, ...); ...> } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... return - snprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... return - scnprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; expression chr; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... return - strcpy(buf, chr); + sysfs_emit(buf, chr); ...> } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; identifier len; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... len = - sprintf(buf, + sysfs_emit(buf, ...); ...> return len; } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; identifier len; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... len = - snprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> return len; } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; identifier len; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... len = - scnprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> return len; } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; identifier len; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { <... - len += scnprintf(buf + len, PAGE_SIZE - len, + len += sysfs_emit_at(buf, len, ...); ...> return len; } @@ //identifier d_show =~ "^.*show.*$"; identifier d_show; identifier dev, attr, buf; expression chr; @@ ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf) { - strcpy(buf, chr); - return strlen(buf); + return sysfs_emit(buf, chr); } @@ identifier k_show =~ "^.*show.*$"; identifier arg1, arg2, arg3; @@ ssize_t k_show(struct kobject * - arg1 + kobj , struct kobj_attribute * - arg2 + attr , char * - arg3 + buf ) { ... ( - arg1 + kobj | - arg2 + attr | - arg3 + buf ) ... } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... return - sprintf(buf, + sysfs_emit(buf, ...); ...> } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... return - snprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... return - scnprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; expression chr; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... return - strcpy(buf, chr); + sysfs_emit(buf, chr); ...> } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; identifier len; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... len = - sprintf(buf, + sysfs_emit(buf, ...); ...> return len; } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; identifier len; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... len = - snprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> return len; } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; identifier len; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... len = - scnprintf(buf, PAGE_SIZE, + sysfs_emit(buf, ...); ...> return len; } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; identifier len; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { <... - len += scnprintf(buf + len, PAGE_SIZE - len, + len += sysfs_emit_at(buf, len, ...); ...> return len; } @@ identifier k_show =~ "^.*show.*$"; identifier kobj, attr, buf; expression chr; @@ ssize_t k_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - strcpy(buf, chr); - return strlen(buf); + return sysfs_emit(buf, chr); } // Rename the sysfs_emit assigned variables not named len and not already int // and set the name to len and type to int @not_int_not_len exists@ type T != int; identifier x != len; position p; identifier sysfs =~ "^sysfs_emit.*$"; assignment operator aop; @@ T x@p; ... x aop sysfs(...) ... @@ type not_int_not_len.T; identifier not_int_not_len.x; position not_int_not_len.p; @@ - T x@p; + int len; <... - x + len ...> // Rename the already int sysfs_emit assigned variables not named len // and set the name to len @int_not_len exists@ type T = int; identifier x != len; position p; identifier sysfs =~ "^sysfs_emit.*$"; assignment operator aop; @@ T x@p; ... x aop sysfs(...) ... @@ type int_not_len.T; identifier int_not_len.x; position int_not_len.p; @@ - T x@p; + int len; <... - x + len ...> // Rename the non-int int sysfs_emit assigned variables named len // and set the type to int @not_int_has_len exists@ type T != int; identifier x = len; position p; identifier sysfs =~ "^sysfs_emit.*$"; assignment operator aop; @@ T x@p; ... x aop sysfs(...) ... @@ type not_int_has_len.T; identifier not_int_has_len.x; position not_int_has_len.p; @@ - T x@p; + int len;