The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Joe Perches <joe@perches.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>,
	Kees Cook <keescook@chromium.org>,
	"Gustavo A . R . Silva" <gustavoars@kernel.org>,
	Denis Efremov <efremov@linux.com>,
	Julia Lawall <julia.lawall@inria.fr>,
	Alex Dewar <alex.dewar90@gmail.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sysfs: Add sysfs_emit to replace sprintf to PAGE_SIZE buffers.
Date: Sat, 29 Aug 2020 08:51:25 +0200	[thread overview]
Message-ID: <20200829065125.GA94642@kroah.com> (raw)
In-Reply-To: <2acf2dc0945bc7f1ec2617b616808ab3c514067b.camel@perches.com>

On Fri, Aug 28, 2020 at 11:41:00PM -0700, Joe Perches wrote:
> On Sat, 2020-08-29 at 08:22 +0200, Greg Kroah-Hartman wrote:
> > On Fri, Aug 28, 2020 at 03:52:13PM -0700, Joe Perches wrote:
> > > sprintf does not know the PAGE_SIZE maximum of the temporary buffer
> > > used for outputting sysfs content requests and it's possible to
> > > overrun the buffer length.
> > > 
> > > Add a generic sysfs_emit mechanism that knows that the size of the
> > > temporary buffer and ensures that no overrun is done.
> > > 
> > > Signed-off-by: Joe Perches <joe@perches.com>
> > > ---
> > >  fs/sysfs/file.c       | 30 ++++++++++++++++++++++++++++++
> > >  include/linux/sysfs.h |  8 ++++++++
> > >  2 files changed, 38 insertions(+)
> > > 
> > > diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
> > > index eb6897ab78e7..06a13bbd7080 100644
> > > --- a/fs/sysfs/file.c
> > > +++ b/fs/sysfs/file.c
> > > @@ -707,3 +707,33 @@ int sysfs_change_owner(struct kobject *kobj, kuid_t kuid, kgid_t kgid)
> > >  	return 0;
> > >  }
> > >  EXPORT_SYMBOL_GPL(sysfs_change_owner);
> > > +
> > > +/**
> > > + *	sysfs_emit - scnprintf equivalent, aware of PAGE_SIZE buffer.
> > > + *	@buf:	start of PAGE_SIZE buffer.
> > > + *	@pos:	current position in buffer
> > > + *              (pos - buf) must always be < PAGE_SIZE
> > 
> > sysfs files are always supposed to be "one value per file", so why would
> > you ever need a 'pos' variable to show the location in the buffer?
> 
> I've done treewide conversions using cocci.
> It's used all over the place.
> Especially in loops with arrays.
> 
> Sometimes the output is single line.
> Sometimes multiple lines.
> 
> Look at the sample conversion of mem_sleep_show I posted earlier.
> 
> #ifdef CONFIG_SUSPEND
>  static ssize_t mem_sleep_show(struct kobject *kobj, struct kobj_attribute *attr,
>                               char *buf)
>  {
> -       char *s = buf;
> +       char *pos = buf;
>         suspend_state_t i;
>  
>         for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
>                 if (mem_sleep_states[i]) {
>                         const char *label = mem_sleep_states[i];
>  
>                         if (mem_sleep_current == i)
> -                               s += sprintf(s, "[%s] ", label);
> +                               pos += sysfs_emit(buf, pos, "[%s] ", label);
>                         else
> -                               s += sprintf(s, "%s ", label);
> +                               pos += sysfs_emit(buf, pos, "%s ", label);
>                 }
>  
>         /* Convert the last space to a newline if needed. */
> -       if (s != buf)
> -               *(s-1) = '\n';
> +       if (pos != buf)
> +               *(pos - 1) = '\n';
>  
> -       return (s - buf);
> +       return pos - buf;
>  }

And again, this is the rare exception, not the rule, please do not make
a generic helper function "easy" to do crazy things like this in sysfs.

Heck, make it explicit, call this function sysfs_emit_pos() and the
non-pos version sysfs_emit().  That way I can easily search for the
"offending" users of the sysfs api.

thanks,

greg k-h

  reply	other threads:[~2020-08-29  6:51 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-28 22:52 [PATCH] sysfs: Add sysfs_emit to replace sprintf to PAGE_SIZE buffers Joe Perches
2020-08-29  6:22 ` Greg Kroah-Hartman
2020-08-29  6:41   ` Joe Perches
2020-08-29  6:51     ` Greg Kroah-Hartman [this message]
2020-08-29  6:59 ` Denis Efremov
2020-08-29  7:13   ` Joe Perches
2020-08-29 21:53     ` Denis Efremov
2020-08-29 23:49       ` Joe Perches

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200829065125.GA94642@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=alex.dewar90@gmail.com \
    --cc=efremov@linux.com \
    --cc=gustavoars@kernel.org \
    --cc=joe@perches.com \
    --cc=julia.lawall@inria.fr \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox