lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Fri, 23 Sep 2022 21:39:08 -0400
From:   Kent Overstreet <kent.overstreet@...ux.dev>
To:     Petr Mladek <pmladek@...e.com>
Cc:     linux-kernel@...r.kernel.org,
        "Matthew Wilcox (Oracle)" <willy@...radead.org>,
        Steven Rostedt <rostedt@...dmis.org>,
        Sergey Senozhatsky <senozhatsky@...omium.org>,
        Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
        Rasmus Villemoes <linux@...musvillemoes.dk>,
        John Ogness <john.ogness@...utronix.de>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Andrew Morton <akpm@...ux-foundation.org>,
        Ingo Molnar <mingo@...hat.com>,
        Dan Williams <dan.j.williams@...el.com>,
        Michal Hocko <mhocko@...e.com>,
        Bjorn Helgaas <helgaas@...nel.org>,
        Christoph Hellwig <hch@...radead.org>,
        Dmitry Torokhov <dmitry.torokhov@...il.com>,
        Al Viro <viro@...iv.linux.org.uk>
Subject: Re: [PATCH v5 00/32] Printbufs

On 9/23/22 03:10, Petr Mladek wrote:
> It seems that the motivation for the pretty print is to allow
> printing more pretty/fancy multi-line debug messages. The API
> should be usable inside vsprintf.c and also outside.
> 
> 1. vsprintf() is very important core API. It is used (not only for)
>     when kernel wants to provide a human readable feedback, for
>     example, via printk(), trace_printk(), procfs, sysfs, debugfs.
> 
>     If a bug in vsprintf() blocks printk()/trace_printk() then
>     crash_dump might be the only way to debug the kernel.

All the more reason for that code to be written with safe APIs, wouldn't 
you say?

> 2. My experience with printk() is that external APIs are big source of
>     problems. Some of them are even solved by hacks, for example:
> 
>       + Console drivers have to check oops_in_progress before taking
>         port->lock to prevent a deadlock.
> 
>       + printk_deferred() or printk_once() have to be used by code that
>         might be called by printk().
> 
>      This patchset adds another external API.

We should differentiate between sprintf and printk.

sprintf is _just_ for formatting strings, it doesn't have the same 
concerns as printk re: locking the output buffer - or any locking 
concerns whatsover, it's a pure function that doesn't mutate outside 
system state.

This patch series is about introducing a safe common API for sprintf and 
other code that outputs to strings, and I'd also note that even Linus 
agreed on the need for such an API, because it gets rid of the separate 
stack-allocated buffers that have been a problem in the past.

There's no impact on printk. The extra feature that printbufs add - heap 
allocation - isn't used by printk.


>      The %pf feature allows writing crazy callbacks called inside
>      vsprintf()/printk() without any proper review and self-tests.

I came to similar conclusions about %pf after the discussion with Linus; 
that part has been dropped from the patch set for now.

I do think we can do it safely in the future, and in the meantime it 
_may_ be worthwhile for use in a much more limited - probably not, I'd 
rather hold off and do it right. But since it hasn't been in the patch 
set the last few times I posted it, let's leave this out of the discussion.

(I think the way to make it safe will be to output to a heap allocated 
buffer instead of the printk buffer directly; however, that's not an 
option currently because we'd need to plumb through a gfp flags 
parameter and obviously we're not going to do that to printk. However, 
we're looking at switching from gfp flags to the memalloc_*() API, which 
would make this work).

>      People would want to extend the pretty print API for a
>      profs/sysfs/debugfs use-case. They would take it easily.
>      There is a lower risk in this case because only a particular
>      file is affected, the API is called in a well defined context.
>      But it looks like a call for problems if we allow to call
>      the same complicated code also from vsprintf() or printk()
>      in any context.

Since %pf isn't getting added, this isn't a concern.

_But_, introducing a common API so that we can use the same code for 
outputting to the system console, or procfs, or debugfs, is precisely 
what this is all about! We've got a fair amount of code duplication 
(some of which this patch series addresses; see the hexdump patches) 
because of this lack of a common API - often messily, with subtle 
differences for absolutely no reason.

We _want_ common, reusable, generic code.

Without %pf, to use printbuf code for outputting to the console the 
standard approach is going to be something like

struct printbuf buf = PRINTBUF;

prt_foo(&buf, foo);
printk("%s\n", buf.buf);
printbuf_exit(&buf);

Obviously, this isn't the greatest ergonomic-wise, %pf would be better 
in that respect. But this is still quite a bit better than completely 
duplicated code - one for outputting to a seq_buf, another set for 
seq_file, another for printk()...

I also have a patch series in the works for a printbuf based replacement 
for seq_file - eliminating that API fragmentation as well. I've just 
been waiting for movement on this patch series...

> 3. Features usually complicate the code immediately or later.
> 
>     For example, the record based ring buffer complicated the printk()
>     code a lot. It introduced many regressions. Development of the
>     lockless variant was a real challenge. And it did not solve
>     everything. Peple still complain that pr_cont() is not reliable.
>     Multi-line output might be mixed, ...

I'm not seeing the complications this patch series introduces in its 
current form. There's heap allocation, which replaces open-coded output 
buffer allocation that's currently done all over the place. And there's 
tabstops and indenting; given the amount of columnar data presented in 
procfs and debugfs, I think those are reasonable additions.

In return, you get a whole ton of code that was previously using raw 
pointer arithmetic converted to safe APIs, and we have a start on 
standardizing a lot of different code on a common API.

And, the sprintf code ends up a whole lot more readable and easier to 
work on.

>     The pretty print API is actually designed for multi-line output.
>     But it will not help when used with printk() that uses 1k buffers
>     internally. And adding support for "unlimited" printk() messages
>     would be another challenge. It would bring new problems,
>     for example, one printk() caller might block others for too long, ...

I'm not seeing that this is a real difficulty, since we're not doing %pf 
at this time.

  - add a printk_string_as_lines(), which takes a string buffer (not a 
format string) and calls printk() on it one line at a time. This would 
be an easy way around the current 1k buffer.
  - or, if the printk code wants to keep the output lines together and 
not have them interspersed with other output, that should be easier when 
we're presenting you the output already formatted and all you need to do 
is memcpy().

Basically, we've got broad agreement that calling arbitrary 
pretty-printers from printk() context is a bad idea, so since we won't 
be doing that this looks like a non-issue to me as well.

>      A more detailed review of the patchset would help me to have
>      stronger opinion about it. I am not clever and experienced enough
>      to see all the consequences on the first look.

There's really not a lot in the way of functional changes, since %pf has 
been dropped - it's just refactoring and converting to common APIs, and 
it was pretty mechanical as far as refactorings go.

Besides what we've talked about, the other thing I was doing that might 
be worth discussing was working on separating the pretty-printers in 
vsprintf.c from the format string parsing code. What I was seeing was a 
lot of code mixing parsing of the format string, and I think that code 
would be _much_ easier to read and work on with the format string 
parsing confined to pointer(), and having it call pretty-printers with a 
normal function call interface with well-typed arguments.

I have additional patches finishing this work for around half of the 
pretty-printers in vsprintf.c, but you were complaining about the patch 
series growing, so I haven't posted them yet...

Anyways, I hope this addresses some concerns.

Cheers,
Kent

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ