mirror of
https://github.com/ceph/ceph
synced 2025-02-22 02:27:29 +00:00
pybind: ceph_argparse: validate incorrectly formed targets
Prior to this patch find_cmd_target() would perform the following parsing for any given command: - check if it's a "tell" to a parseable CephName (i.e., ceph tell <type.id> ...) - if so, return <type>, <id> - check if it's a "tell" to a parseable PG id (e.g., ceph tell 0.4a) - if so, return 'pg', <pgid> - check if it's a "pg" command to a parseable PG id (e.g., ceph pg 0.4a) - if so, return 'pg', <pgid> - otherwise return 'mon', '' However, parsing of CephName and CephPgid is performed in a relaxed fashion, and tightening those checks requirements end up having nefarious effects on properly formed commands, whereas keeping them relaxed ends up having us returning 'mon','' in the end for a clearly malformed target (e.g., 'ceph tell foo ...'). This patch fixes this behavior by adding a new check: - if command is a "tell" and we were not able to parse either a CephName nor a PG id, then explicitely validate the target as a CephName (given we would be sending to a monitor anyway, we can just as well validate a 'tell' as a CephName). - if validation fails, we will propagate exceptions referring to the cause of the validation failure. Fixes: #10439 Signed-off-by: Joao Eduardo Luis <joao@redhat.com>
This commit is contained in:
parent
8618a5373e
commit
c4548f68ca
14
src/ceph.in
14
src/ceph.in
@ -425,7 +425,12 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
|
||||
if interactive_input in ['q', 'quit', 'Q']:
|
||||
return 0, '', ''
|
||||
cmdargs = parse_cmdargs(interactive_input.split())[2]
|
||||
target = find_cmd_target(cmdargs)
|
||||
try:
|
||||
target = find_cmd_target(cmdargs)
|
||||
except Exception as e:
|
||||
print >> sys.stderr, \
|
||||
'error handling command target: {0}'.format(e)
|
||||
return 1
|
||||
valid_dict = validate_command(sigdict, cmdargs, verbose)
|
||||
if valid_dict:
|
||||
if parsed_args.output_format:
|
||||
@ -753,7 +758,12 @@ def main():
|
||||
if parsed_args.status:
|
||||
childargs.insert(0, 'status')
|
||||
|
||||
target = find_cmd_target(childargs)
|
||||
try:
|
||||
target = find_cmd_target(childargs)
|
||||
except Exception as e:
|
||||
print >> sys.stderr, \
|
||||
'error handling command target: {0}'.format(e)
|
||||
return 1
|
||||
|
||||
# Repulsive hack to handle tell: lop off 'tell' and target
|
||||
# and validate the rest of the command. 'target' is already
|
||||
|
@ -1005,6 +1005,30 @@ def find_cmd_target(childargs):
|
||||
# pg doesn't need revalidation; the string is fine
|
||||
return 'pg', valid_dict['pgid']
|
||||
|
||||
# If we reached this far it must mean that so far we've been unable to
|
||||
# obtain a proper target from childargs. This may mean that we are not
|
||||
# dealing with a 'tell' command, or that the specified target is invalid.
|
||||
# If the latter, we likely were unable to catch it because we were not
|
||||
# really looking for it: first we tried to parse a 'CephName' (osd, mon,
|
||||
# mds, followed by and id); given our failure to parse, we tried to parse
|
||||
# a 'CephPgid' instead (e.g., 0.4a). Considering we got this far though
|
||||
# we were unable to do so.
|
||||
#
|
||||
# We will now check if this is a tell and, if so, forcefully validate the
|
||||
# target as a 'CephName'. This must be so because otherwise we will end
|
||||
# up sending garbage to a monitor, which is the default target when a
|
||||
# target is not explicitly specified.
|
||||
# e.g.,
|
||||
# 'ceph status' -> target is any one monitor
|
||||
# 'ceph tell mon.* status -> target is all monitors
|
||||
# 'ceph tell foo status -> target is invalid!
|
||||
if len(childargs) > 1 and childargs[0] == 'tell':
|
||||
name = CephName()
|
||||
# CephName.valid() raises on validation error; find_cmd_target()'s
|
||||
# caller should handle them
|
||||
name.valid(childargs[1])
|
||||
return name.nametype, name.nameid
|
||||
|
||||
sig = parse_funcsig(['pg', {'name':'pgid', 'type':'CephPgid'}])
|
||||
try:
|
||||
valid_dict = validate(childargs, sig, partial=True)
|
||||
|
Loading…
Reference in New Issue
Block a user