mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
fcdfb151e2
A user can create a large demand paged segment and then do write to a ctl file with a very large buffer driving the kernel into an out-of-memory condition. For all practcal purposes, limit the input buffer size to something reasonable. READSTR is 8000 bytes, which would be enougth for even the largest ctl messages.
115 lines
2.1 KiB
Text
115 lines
2.1 KiB
Text
.TH PARSECMD 9
|
|
.SH NAME
|
|
parsecmd, cmderror, lookupcmd
|
|
\- parse device commands
|
|
.SH SYNOPSIS
|
|
.ta \w'\fLCmdbuf* 'u
|
|
.B
|
|
Cmdbuf* parsecmd(char *a, int n)
|
|
.PP
|
|
.B
|
|
void cmderror(Cmdbuf *cb, char *s)
|
|
.PP
|
|
.B
|
|
Cmdtab* lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab)
|
|
.SH DESCRIPTION
|
|
.I Parsecmd
|
|
is an interface to
|
|
.I tokenize
|
|
(see
|
|
.IR getfields (2)),
|
|
that safely parses a command, with blank-separated fields, as might be
|
|
written to a device's
|
|
.B ctl
|
|
file.
|
|
The buffer
|
|
.I a
|
|
and count
|
|
.I n
|
|
can be those passed to the driver's
|
|
.I write
|
|
function.
|
|
.I Parsecmd
|
|
converts the byte array (which might not be null-terminated) to a null-terminated string,
|
|
trimming any trailing new line,
|
|
before invoking
|
|
.I tokenize
|
|
to break the string into arguments, interpreting blank and tab as field separators
|
|
when they are not quoted
|
|
(in the style of
|
|
.IR rc (1)).
|
|
It returns a pointer to a dynamically-allocated
|
|
.B Cmdbuf
|
|
structure,
|
|
which holds a copy of the string and the resulting fields; it is
|
|
defined as follows:
|
|
.IP
|
|
.EX
|
|
.ta 6n +\w'char* 'u
|
|
typedef
|
|
struct Cmdbuf
|
|
{
|
|
char *buf;
|
|
char **f;
|
|
int nf;
|
|
} Cmdbuf;
|
|
.EE
|
|
.PP
|
|
The array
|
|
.B f
|
|
holds the field pointers;
|
|
.B nf
|
|
gives the number of fields.
|
|
.B Cmdbuf
|
|
is allocated by
|
|
.I smalloc
|
|
(see
|
|
.IR malloc (9)),
|
|
and the caller is responsible for freeing it using
|
|
.IR free .
|
|
To prevent denial of service to the kernel,
|
|
.I parsecmd
|
|
will error out if
|
|
.I n
|
|
exceeds
|
|
.B READSTR
|
|
bytes.
|
|
.PP
|
|
.I Cmderror
|
|
prepends the given format with the original command,
|
|
then calls
|
|
.IR error (9).
|
|
.PP
|
|
Command strings may be turned into a (typically enumerated)
|
|
integer with
|
|
.IR lookupcmd .
|
|
The catchall
|
|
.L *
|
|
matches any text. Unrecognized commands, or commands
|
|
given an unacceptable number of arguments generate a
|
|
call to
|
|
.IR error .
|
|
The definition is as follows
|
|
.IP
|
|
.EX
|
|
.ta 6n +\w'char* 'u
|
|
typedef
|
|
struct Cmdtab
|
|
{
|
|
int index; /* used by client to switch on result */
|
|
char *cmd; /* command name */
|
|
int narg; /* expected #args; 0 ==> variadic */
|
|
} Cmdtab;
|
|
.EE
|
|
.PP
|
|
The integer
|
|
.B index
|
|
is the number returned on command match.
|
|
The string
|
|
.B cmd
|
|
is the command name, and
|
|
.B narg
|
|
is 0 (indicating a variadic function) or the
|
|
number of arguments.
|
|
.SH SOURCE
|
|
.B /sys/src/9/port/parse.c
|