[HN Gopher] Linux /proc/pid/stat parsing bugs
___________________________________________________________________
Linux /proc/pid/stat parsing bugs
Author : ototot
Score : 80 points
Date : 2022-12-22 14:54 UTC (8 hours ago)
(HTM) web link (www.openwall.com)
(TXT) w3m dump (www.openwall.com)
| inetknght wrote:
| It's almost as if there should be an API for procfs instead of
| having everyone write their own reader and parser...
| mzs wrote:
| > sudo was bitten by this back in the day (CVE-2017-1000367):
|
| > https://www.openwall.com/lists/oss-security/2017/05/30/16
|
| https://www.openwall.com/lists/oss-security/2022/12/22/5
| YesThatTom2 wrote:
| If there is exactly one field with the "may contain spaces"
| problem there's a better solution: parse the line forwards for
| the fields up to that one, parse the line backwards for the
| remaining.
| jwilk wrote:
| How is that better than looking for the last ")" character?
|
| Besides, it wouldn't work, because you don't know in advance
| how many fields are there.
| smasher164 wrote:
| makes you wonder if it's really that valuable to have all our
| infrastructure built on parsing text
| raldi wrote:
| Or to have filesystems that support names with every character
| but slash and NUL.
| capitol_ wrote:
| I agree, not supporting NUL is really a historical c-ism that
| we should get rid of.
|
| /s
| mort96 wrote:
| I've been bitten by and tried to work around this as well. From
| what I can tell, the best you can really do is to parse by
| matching up parens, but someone could totally make a program with
| braces in its name. If I make a binary called "foo) R 10 20 30",
| the /proc/<pid>/stat entry will contain "1715376 (foo) R 10 20
| 30) 1544883 1715376 1544883...". It's terribly non-obvious how to
| deal with correctly.
| [deleted]
| st_goliath wrote:
| > It's terribly non-obvious how to deal with correctly.
|
| Like the post says: read the whole thing into memory and do a
| _reverse_ search for the _last_ ')', i.e. strrchr
|
| Once you are aware of the problem, it's obvious how to solve
| it, but I do agree that the hidden danger here is not
| immediately obvious at first.
| zokier wrote:
| Note that man page says that the name is truncated to 16
| chars, so if for whatever reason you don't want to do
| unbounded length read then you can use that
| jyxent wrote:
| They actually allow up to 64 characters in the kernel: http
| s://github.com/torvalds/linux/blob/8395ae05cb5a2e31d3610...
|
| This might just be for certain kernel things though. I
| don't see any regular processes that aren't truncated, but
| I see a bunch of kernel things that have more than 16 chars
| on my system.
| [deleted]
| esprehn wrote:
| The system level fix is to create a structured record format.
| That could mean quoting all the records or maybe Linux should
| finally adopt a standardized format like JSON.
| zokier wrote:
| Strictly speaking it is structured; the structure is described
| in the man page and it is machine-parseable
| jwilk wrote:
| It's not described correctly. The man page says you can parse
| it with scanf(), which is wrong.
| xeeeeeeeeeeenu wrote:
| In my opinion, the fact that procfs is the only API for so many
| things is one of the biggest problems with Linux. BSDs have
| sysctl(), macOS has mach_* functions and, of course, Windows has
| a real API too.
|
| Plain text interfaces lead to complicated, potentially insecure
| code (especially in C!), they're prone to race conditions and
| slow.
|
| I wish it was possible to retrieve that information using real
| syscalls. I think it's a better approach than, for example,
| inventing a faster way to read procfs:
| https://lwn.net/Articles/813827/
| woodruffw wrote:
| Linux does have libproc, which is meant (IIUC) to mirror the
| BSD-style libproc. It wouldn't surprise me if it's just parsing
| the same files under the hood, however, and correspondingly has
| the same bugs. But then again, bugs in one place is potentially
| a better state of affairs than bugs in many places (?).
| the8472 wrote:
| Having C functions isn't all that much better. You have
| replaced a crufty text format with crufty data structures full
| of paddings, unions, bitfields, VLAs, unaligned nested structs
| and other crazy stuff. Look at ioctls or cmsg. With C structs +
| 3rd-party kernel drivers you can even get UB because the driver
| returns data that is invalid under the struct definition (e.g.
| incorrect alignment, invalid bools).
| touisteur wrote:
| I think a proper formal grammar would do the trick, with
| maybe a canonical implementation...
| CamJN wrote:
| MacOS' KERN_PROCARGS2 sysctl is an exception to this, it is
| very unintuitive to parse and every single piece of code that
| tries to parse the results that I've found on the internet has
| been wrong, including those from Apple, Google, and Microsoft.
| I wound up making a library to do it
| (https://getargv.narzt.cam/) because apparently people need
| help.
| convolvatron wrote:
| I just ran into this and its not documented and there are
| very examples. I will definitely be looking at your library,
| thank you.
|
| it sounds fishy, but just because sysctl is a mess doesn't
| necessarily imply that structured kernel interfaces are a bad
| idea
| touisteur wrote:
| Netlink is the place to look for some of these info,
| https://twitter.com/dvyukov/status/1605539242506997765 . Loads
| and loads of stuff in netlink.
| hamburglar wrote:
| Totally agreed. Any time I've found myself parsing proc, I've
| felt like I was doing something foolish and unsafe in lieu of a
| "real" api.
| xxpor wrote:
| Even if they insist on a file based interface (it is a UNIX, so
| fair enough), in modern times it would be nice if they used a
| "real" data format. Yeah, it's not like JSON parsers have never
| had bugs, but on average they'll be MUCH better than everyone
| and their mother hand rolling a C based bespoke parser.
| Obviously you'd need a new name to not break backwards
| compatibility.
| kbrazil wrote:
| jc[0] supports proc files. Converts them to JSON or YAML. (I
| am the author)
|
| [0] https://kellyjonbrazil.github.io/jc/docs/parsers/proc
| prattmic wrote:
| Neat! Your parser [1] almost has a similar issue because a
| comm could contain parenthesis, e.g., `foo) R 123 456`. But
| since a comm is limited to 64 bytes, I don't think it is
| possible to fit a fully matching string inside of the comm
| before the closing parent after the comm, which would thus
| make your regexp fail to match.
|
| [1] https://github.com/kellyjonbrazil/jc/blob/master/jc/par
| sers/...
| henrydark wrote:
| I just had a quick read of the pid/stat parser, and the
| regex pattern starts with ^, but there's no $. Doesn't this
| mean that this parser suffers exactly the bug of the
| original post?
| prattmic wrote:
| See https://news.ycombinator.com/item?id=34097179. A comm
| is limited to 64 bytes, so I don't think it is possible
| to fit a long enough comm to match the full regexp.
| henrydark wrote:
| Right, it's not a security problem on its own, but it can
| make the regex not match at all causing jc to return an
| error. So jc suffers from the parsing bug mentioned in
| the post.
|
| [edit:] In order to get jc to return an error one has to
| actually read the regex. Here is a file name that gets it
| to return an error: bad) S 1 2 3 4 5
| kbrazil wrote:
| Interesting - the proc-pid-parser actually parses that
| file name just fine: $ echo '2001 (bad)
| S 1 2 3 4 5) S 1888 2001 1888 34816 2001 4202496 428 0 0
| 0 0 0 0 0 20 0 1 0 75513 115900416 297
| 18446744073709551615 4194304 5100612 140737020052256
| 140737020050904 140096699233308 0 65536 4 65538
| 18446744072034584486 0 0 17 0 0 0 0 0 0 7200240 7236240
| 35389440 140737020057179 140737020057223 140737020057223
| 140737020059606 0' | jc --proc-pid-stat
| {"pid":2001,"comm":"bad) S 1 2 3 4 5","state":"S","ppid":
| 1888,"pgrp":2001,"session":1888,"tty_nr":34816,"tpg_id":2
| 001,"flags":4202496,"minflt":428,"cminflt":0,"majflt":0,"
| cmajflt":0,"utime":0,"stime":0,"cutime":0,"cstime":0,"pri
| ority":20,"nice":0,"num_threads":1,"itrealvalue":0,"start
| time":75513,"vsize":115900416,"rss":297,"rsslim":18446744
| 073709551615,"startcode":4194304,"endcode":5100612,"start
| stack":140737020052256,"kstkeep":140737020050904,"kstkeip
| ":140096699233308,"signal":0,"blocked":65536,"sigignore":
| 4,"sigcatch":65538,"wchan":18446744072034584486,"nswap":0
| ,"cnswap":0,"exit_signal":17,"processor":0,"rt_priority":
| 0,"policy":0,"delayacct_blkio_ticks":0,"guest_time":0,"cg
| uest_time":0,"start_data":7200240,"end_data":7236240,"sta
| rt_brk":35389440,"arg_start":140737020057179,"arg_end":14
| 0737020057223,"env_start":140737020057223,"env_end":14073
| 7020059606,"exit_code":0,"state_pretty":"Sleeping in an
| interruptible wait"}
|
| But the "magic" signature doesn't recognize it:
| $ echo '2001 (bad) S 1 2 3 4 5) S 1888 2001 1888 34816
| 2001 4202496 428 0 0 0 0 0 0 0 20 0 1 0 75513 115900416
| 297 18446744073709551615 4194304 5100612 140737020052256
| 140737020050904 140096699233308 0 65536 4 65538
| 18446744072034584486 0 0 17 0 0 0 0 0 0 7200240 7236240
| 35389440 140737020057179 140737020057223 140737020057223
| 140737020059606 0' | jc --proc jc:
| Error - Parser issue with proc:
| ParseError: Proc file could not be identified.
| ...
|
| I can fix the "magic" signature (regex) to account for
| such cases.
| kbrazil wrote:
| It doesn't look like jc suffers from this bug since the
| regex match is greedy: % echo '2001 (my
| (file) with) S 1888 2001 1888 34816 2001 4202496 428 0 0
| 0 0 0 0 0 20 0 1 0 75513 115900416 297
| 18446744073709551615 4194304 5100612 140737020052256
| 140737020050904 140096699233308 0 65536 4 65538
| 18446744072034584486 0 0 17 0 0 0 0 0 0 7200240 7236240
| 35389440 140737020057179 140737020057223 140737020057223
| 140737020059606 0' | jc --proc
| {"pid":2001,"comm":"my (file) with","state":"S","ppid":18
| 88,"pgrp":2001,"session":1888,"tty_nr":34816,"tpg_id":200
| 1,"flags":4202496,"minflt":428,"cminflt":0,"majflt":0,"cm
| ajflt":0,"utime":0,"stime":0,"cutime":0,"cstime":0,"prior
| ity":20,"nice":0,"num_threads":1,"itrealvalue":0,"startti
| me":75513,"vsize":115900416,"rss":297,"rsslim":1844674407
| 3709551615,"startcode":4194304,"endcode":5100612,"startst
| ack":140737020052256,"kstkeep":140737020050904,"kstkeip":
| 140096699233308,"signal":0,"blocked":65536,"sigignore":4,
| "sigcatch":65538,"wchan":18446744072034584486,"nswap":0,"
| cnswap":0,"exit_signal":17,"processor":0,"rt_priority":0,
| "policy":0,"delayacct_blkio_ticks":0,"guest_time":0,"cgue
| st_time":0,"start_data":7200240,"end_data":7236240,"start
| _brk":35389440,"arg_start":140737020057179,"arg_end":1407
| 37020057223,"env_start":140737020057223,"env_end":1407370
| 20059606,"exit_code":0,"state_pretty":"Sleeping in an
| interruptible wait"}
|
| Edit: looks like I can tighten up the signature matching
| regex for the "magic" syntax per the issue found above.
| The greedy regex matching for the parser does seem to
| work fine, though.
| rdtsc wrote:
| > Yeah, it's not like JSON parsers have never had bugs, but
| on average they'll be MUCH better than everyone and their
| mother hand rolling a C based bespoke parser.
|
| Currently, but if this idea started when Linux was become
| popular the real data format would have been XML. It might
| have been nice at the time, but today we would have laughed
| at it and said how outdated and silly it looks probably.
| woodruffw wrote:
| People make fun of the excesses of the XML era, but that
| would still be an improvement in the state of affairs!
|
| Realistically, however, a reasonable format here would be
| CSV/TSV with a bit of escaping, or even something like
| netstrings[1]. Either would be unambiguous, while retaining
| the shell-tool-friendly nature of these pseudofiles.
|
| [1]: https://cr.yp.to/proto/netstrings.txt
| marcodiego wrote:
| I love the fact that I can play with the leds of my device
| without specialized tools. Yes, it is sysfs, not procfs, but it
| is the same idea.
| nijave wrote:
| Many of the APIs on Windows are pretty trivial to interact
| with using PowerShell commandlets. Similarly, many SaaS based
| tools have CLIs to interact with their arbitrarily complex
| APIs.
|
| You can still have easy abstractions while providing a way
| around them for times they don't work well (acquiring
| structured data)
| ilyt wrote:
| I wish /proc|/sys would just agree on serialization format and
| just serialize the data into some defined format instead of
| having a bunch of files that all need their own parser
| ajross wrote:
| FWIW: sysfs tried to do this already. In general each node
| corresponds to one "thing", with a reasonably standard set of
| stringification schemes, and with a path that acts as a self-
| describing schema. Obviously in _practice_ it ends up that
| every driver or subsystem ends up doing funny nonsense (e.g.
| uevent nodes have their own sub-schema with shell-style
| variables, etc...).
|
| You can't really prevent that. People do funny nonsense in
| other self-describing data formats like JSON and XML all the
| time too. There's only so much you can do with a framework.
|
| But /proc is... extremely old, and very heavily used by
| userspace. In practice it's never going to change.
| ilyt wrote:
| > You can't really prevent that. People do funny nonsense in
| other self-describing data formats like JSON and XML all the
| time too. There's only so much you can do with a framework.
|
| Sure but you will get more of that if the convention is too
| simplistic. "one file per value" breaks really fast, just cat
| /proc/net/nf_conntrack or even just proc/<pid>/stats and see
| just how many values single entry (file/connection) has.
|
| Doesn't need to be some ASN.1 monstrosity, could be simple
| conventions like "this is how key/value proc/sys file should
| look, this is how tabular file should look etc."
|
| Make all escaping use same syntax, make every table separator
| be \t etc.
|
| > But /proc is... extremely old, and very heavily used by
| userspace. In practice it's never going to change.
|
| eh, just mount it in /proc2
| eminence32 wrote:
| I've been working on a library[1] that aims to have fairly
| complete support for the procfs filesystem, so that you can
| hide away these annoying parsing quirks. But for some casual
| usage of /proc/ where you only need one tiny bit of
| information, it's often better to just roll your own parser
| instead of bringing in a 3rd party library. It's these small
| one-off cases that would really benefit from a standardized
| serialization format like you propose.
|
| [1] https://github.com/eminence/procfs
| idealmedtech wrote:
| It would be great if the kernel itself provided a header only
| definition of such a format, so you could focus on the data
| and not the parsing. Would also be able to integrate into
| their extensive testing infrastructure.
| ilyt wrote:
| Realistically it could stay mostly as-is, some text values
| with separators, just define exactly how to quote stuff and
| what the separator.
|
| Then you could just have "load a single value" function
| that does the unquoting, "load K/V" function for stuff like
| /proc/meminfo, and "load table" for stuff like
| /proc/<pid>/stat. Maybe "load records" for stuff like
| /proc/net/nf_conntrack which is essentially list of KV
| pairs.
| jcelerier wrote:
| we could even name the tool to query such serialized data,
| procctl, provided by the systemd-proc package
| saalweachter wrote:
| While we're wishing in one hand, how is it that our programs
| still take an input of an array of strings, that get escaped
| and unescaped and split randomly by our shell scripts?
| ilyt wrote:
| That is entirely due to sh/bash and friends being a terrible
| programming language.
|
| All sensible ones allow you to just pass an array of
| parameters to command execution and not worry about spaces in
| them
| NathanOsullivan wrote:
| FWIW bash supports arrays, and running commands with an
| array providing the arguments
| saalweachter wrote:
| That's only, like, half the problem.
|
| It's an _array_ of _string parameters_.
|
| No semantics! Just an variety of customs about what it
| means when a parameters begins with a - or a -- or if you
| have -- by itself preceding some characters, how to break
| lists of arguments with separators, what happens when you
| pass the same argument twice, etc etc etc.
|
| To choose the worst possible solution better than that, we
| could instead be passing in a single string with a JSON
| dictionary that says things like '{ "recursive": True,
| "force": True, "files": [ "file1", "file2", "file3" ]}'
| Spivak wrote:
| The irony is that I've had to add shell word splitting into
| in my real programming language code because of how many
| people prefer run(f"command {arg} -v
| -p{opt} {target}")
|
| to run(["command", arg, "-v", "-p", opt,
| target])
| stefan_ wrote:
| Well it's too late now. But I thought the plan was for all of
| that stuff to move to Netlink? Not that that isn't a terrible
| very horrible API either.
| bradfitz wrote:
| Advent of Proc
| st_goliath wrote:
| While procfs has a lot of historical baggage, sysfs is rather
| specific about the layout and providing only a _single_ value
| per file, as plain ASCII, rather than using anything complex
| that has to be parsed. _Structure_ is implemented via the
| filesystem.
|
| In return, the kernel side API for sysfs is also a lot cleaner
| and allows to more-or-less expose individual variables as
| tuning knobs for a driver.
|
| Of course there are edge cases, and there are e.g. some binary
| interfaces as well (e.g. for providing direct register access,
| or implementing a firmware upload interface for a device).
|
| ABI compat issues aside, I think that implementing "a
| standardized [structured] record format" as suggested in the
| comments here is a rather bad idea, going into exactly the
| wrong direction by _adding_ complexity rather than _reducing_
| it, which would definitely cause even more parsing related
| issues in the long run.
| ilyt wrote:
| >While procfs has a lot of historical baggage, sysfs is
| rather specific about the layout and providing only a single
| value per file, as plain ASCII, rather than using anything
| complex that has to be parsed. Structure is implemented via
| the filesystem.
|
| I'd rather have structured file than to have open 30k files
| (for say conntrack)
|
| Hell, just example from the article, /proc/<PID>/stat has 52
| parameters. That would be 52 opens and reads with single
| value per file.
|
| > ABI compat issues aside, I think that implementing "a
| standardized [structured] record format" as suggested in the
| comments here is a rather bad idea, going into exactly the
| wrong direction by adding complexity rather than reducing it,
| which would definitely cause even more parsing related issues
| in the long run.
|
| It's literally the opposite. You have to implement it _once_
| on kernel side and _once_ in userspace vs every special
| format that currently needs
| throwaway09223 wrote:
| Linux has already half-solved this, eg with netlink.
|
| If you're on a system with huge numbers of connections,
| reading from /proc/net/tcp get extremely slow. Modern tools
| query connection state using netlink instead (ss vs
| netstat). This was done by necessity: /proc/net/tcp
| actually doesn't work at scale.
|
| I agree with you, serializing and deserializing files with
| records is a terrible idea - it cannot be performant. JSON
| fixes parsing ambiguity but at a cost of being even slower.
| We already know it won't work.
|
| We have already solved this for specific parts of /proc and
| it works great. All we have to do is finish the work and
| provide the rest of proc via netlink as well (or whatever
| else similar non-text based system for querying structured
| records)
| dale_glass wrote:
| JSON can be parsed very quickly:
| https://github.com/simdjson/simdjson
|
| CBOR could be another option:
| https://en.wikipedia.org/wiki/CBOR
| the8472 wrote:
| JSON cannot be efficient for binary data or even utf8
| strings because it needs escaping which means you can't
| have a zero-copy implementation. CBOR is better in that
| regard, yeah.
| ilyt wrote:
| All it needs to beat is stringifying and formatting that
| /proc|/sys already does
| throwaway09223 wrote:
| It can't (simdjson is fast compared to other text parsing
| - it's still extremely slow compared to native types),
| but that fact actually doesn't matter because the problem
| isn't the parsing. Even the _construction_ of these text
| files in proc is too slow.
|
| You can't _read_ /proc/net/tcp within a reasonable amount
| of time on a system with hundreds of thousands of
| connections. Even allocating/churning memory to store a
| textual representation becomes a problematic overhead.
| st_goliath wrote:
| > You have to implement it _once_ on kernel side and _once_
| in userspace
|
| I actually did think about this before posting my original
| response, and I think this is unrealistic from a practical
| perspective. To elaborate a bit on that:
|
| First of, a one-size-fits-all structured format is _a lot_
| more complex than a directory with ASCII files in it that
| each store an integer and IMO invites itself to feature
| creep (i.e. _more_ complexity).
|
| _Complexity_ is IMO the root cause of the issue originally
| discussed here (if not most bugs). The more code, the more
| complexity, the more bugs. In my experience, software will
| always have bugs, complex software more so.
|
| There can never be a "one-true-implementation" for
| userspace. Because of the complexity, people _will_ write
| their own ad-hoc versions. They "only need that one thing"
| and don't want to drag the whole library dependency in.
| Some people think they know better and write their own
| "lightweight/suckless/..." versions because the kernel one
| is "bloated", or "that API sucks". Some will rewrite it in
| their favorite programming language for whatever reason.
| NIH syndrome, bike shedding, ...
|
| Then, what if a widely used implementation has a bug?
| _Especially_ if it 's the "one-true-library" itself? You
| now need to roll out a fix. Across countless Distros,
| embedded devices that might get maintenance updates every
| couple years at best, set-top boxes, network appliances,
| ... You'll have programs floating around that are
| statically linked against a specific version of the one-
| true-library. In the end, we have a variety of differently
| bugged parsers in use, simply because of the spread in
| versions alone. The original problem that we wanted to
| solve, remains.
|
| Of course there are issues with the more simplistic
| approach, but in the case of e.g. sysfs, those are
| typically corner cases. Adding a one-size-fits-all special,
| structured format for _everything_ introduces a whole lot
| of unneeded complexity everywhere else as well. A "one-
| true-format to solve all problems" that needs special
| library code for processing IMO introduces a whole lot more
| problems than it solves.
| touisteur wrote:
| But for conntrack and highly structured commands and data
| wouldn't you use netlink?
| avar wrote:
| I noticed this around a year ago when writing a /proc/paid/stat
| parser for git (for logging the chain of parent processes).
|
| Here's that commit, it has a comment with an overview of the
| kernel limits and caveats involved:
| https://github.com/git/git/commit/2d3491b117c6dd08e431acc390...
| kbrazil wrote:
| Fortunately `jc`[0] does parse `/proc/<pid>/stat` correctly. I,
| of course, originally implemented it the naive/incorrect way
| until a contributor fixed it. :) $ cat
| /proc/2001/stat | jc --proc {"pid":2001,"comm":"my
| program with\nsp","state":"S","ppid":1888,"pgrp":2001,"session":1
| 888,"tty_nr":34816,"tpg_id":2001,"flags":4202496,"minflt":428,"cm
| inflt":0,"majflt":0,"cmajflt":0,"utime":0,"stime":0,"cutime":0,"c
| stime":0,"priority":20,"nice":0,"num_threads":1,"itrealvalue":0,"
| starttime":75513,"vsize":115900416,"rss":297,"rsslim":18446744073
| 709551615,"startcode":4194304,"endcode":5100612,"startstack":1407
| 37020052256,"kstkeep":140737020050904,"kstkeip":140096699233308,"
| signal":0,"blocked":65536,"sigignore":4,"sigcatch":65538,"wchan":
| 18446744072034584486,"nswap":0,"cnswap":0,"exit_signal":17,"proce
| ssor":0,"rt_priority":0,"policy":0,"delayacct_blkio_ticks":0,"gue
| st_time":0,"cguest_time":0,"start_data":7200240,"end_data":723624
| 0,"start_brk":35389440,"arg_start":140737020057179,"arg_end":1407
| 37020057223,"env_start":140737020057223,"env_end":140737020059606
| ,"exit_code":0,"state_pretty":"Sleeping in an interruptible
| wait"}
|
| [0]
| https://kellyjonbrazil.github.io/jc/docs/parsers/proc_pid_st...
| cryptonector wrote:
| The process name should have been last. Now parsers have to split
| on space and then take the first token and the last N-2 tokens to
| leave behind the tokens that make up the second field, then join
| those with spaces to reconstruct the second field (or use the
| length of the first and the offset of the third fields to re-
| parse the second).
| tatref wrote:
| If you do this, then you can't add new fields
| cryptonector wrote:
| Correct. I guess you could split on parens instead.
| woodruffw wrote:
| The /proc/<pid>/* hierarchy has always been a bit of a mess to
| parse.
|
| /proc/<pid>/maps is similarly frustrating: there's no clear
| distinction between "special" maps (like the stack) and a file
| that might just happen to be named `[stack]`. Similarly, the
| handling for a mapped region on a deleted file is simply to
| append " (deleted)"[1].
|
| [1]:
| https://github.com/woodruffw/procmaps.rs/blob/79bd474104e9b3...
| jbverschoor wrote:
| Why do you have to parse this kind of stuff at all?
|
| Time to let go of the everything is a stream of unorganized
| characters
| bigcat12345678 wrote:
| We are pixie.io ran into exact problem, we fixed that by parsing
| the braces, ugly but seems working
|
| https://github.com/pixie-io/pixie/blob/bd82bb48ef4da7d6b05f2...
| idealmedtech wrote:
| That's exactly how it should be done! Also subtle but important
| that you find the _last_ closing parentheses, as an attacker
| could just include a paren in their process name to terminate
| your parse early.
| horstschneider wrote:
| That is how psmisc does it:
|
| https://gitlab.com/psmisc/psmisc/-/blob/master/src/pstree.c#.
| ..
| qwertox wrote:
| These comments here need more visibility.
| jwilk wrote:
| > if (std::getline(ifs, line)) {
|
| But what if comm contains newlines?
| [deleted]
___________________________________________________________________
(page generated 2022-12-22 23:01 UTC)