Add support for --suggest=phrase to capsh.

Ever wondered something like which capability allows a process
to do privileged things with a tty? Try this:

  capsh --suggest="tty"

cap_sys_tty_config (26) [/proc/self/status:CapXXX: 0x0000000004000000]

    Allows a process to manipulate tty devices:
      - configure tty devices
      - perform vhangup() of a tty

Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
This commit is contained in:
Andrew G. Morgan 2021-05-16 18:36:24 -07:00
parent 572b1f8099
commit 578b4cd7bf
5 changed files with 48 additions and 18 deletions

View File

@ -50,7 +50,7 @@ const (
// file.
FSETID
// KILL allows a process to sent a kill(2) signal to any other
// KILL allows a process to send a kill(2) signal to any other
// process - overriding the limitation that there be a
// [E]UID match between source and target process.
KILL

View File

@ -220,6 +220,10 @@ capability makes available to a running program. Note, instead of
\fIcap_xxx\fP, one can provide a decimal number and \fBcapsh\fP will
look up the corresponding capability's description.
.TP
.BI \-\-suggest= phrase
Scan each of the textual descriptions of capabilities, known to
\fBcapsh\fP, and display all descriptions that include \fIphrase\fP.
.TP
.BI \-\-decode= N
This is a convenience feature. If you look at
.B /proc/1/status

View File

@ -1,3 +1,3 @@
Allows a process to sent a kill(2) signal to any other
Allows a process to send a kill(2) signal to any other
process - overriding the limitation that there be a
[E]UID match between source and target process.

View File

@ -14,6 +14,10 @@
#define _DEFAULT_SOURCE
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -395,6 +399,22 @@ static long safe_sysconf(int name)
return ans;
}
static void describe(cap_value_t cap) {
int j;
const char **lines = explanations[cap];
char *name = cap_to_name(cap);
if (cap < cap_max_bits()) {
printf("%s (%d)", name, cap);
} else {
printf("<reserved for> %s (%d)", name, cap);
}
cap_free(name);
printf(" [/proc/self/status:CapXXX: 0x%016llx]\n\n", 1ULL<<cap);
for (j=0; lines[j]; j++) {
printf(" %s\n", lines[j]);
}
}
int main(int argc, char *argv[], char *envp[])
{
pid_t child;
@ -955,7 +975,7 @@ int main(int argc, char *argv[], char *envp[])
"Copyright (c) 2008-11,16,19-21 Andrew G. Morgan"
" <morgan@kernel.org>\n", argv[0]);
exit(0);
} else if (!strncmp("--explain=", argv[i], 10)) {
} else if (!strncmp("--explain=", argv[i], 10)) {
cap_value_t cap;
if (cap_from_name(argv[i]+10, &cap) != 0) {
fprintf(stderr, "unrecognised value '%s'\n", argv[i]+10);
@ -966,26 +986,31 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
if (cap < CAPSH_DOC_LIMIT) {
int j;
const char **lines = explanations[cap];
char *name = cap_to_name(cap);
if (cap < cap_max_bits()) {
printf("%s (%d)", name, cap);
} else {
printf("<reserved for> %s (%d)", name, cap);
}
cap_free(name);
printf(" [/proc/self/status:CapXXX: 0x%016llx]\n\n", 1ULL<<cap);
for (j=0; lines[j]; j++) {
printf(" %s\n", lines[j]);
}
describe(cap);
continue;
} else if (cap < cap_max_bits()) {
}
if (cap < cap_max_bits()) {
printf("<unnamed in libcap> (%d)", cap);
} else {
printf("<unsupported> (%d)", cap);
}
printf(" [/proc/self/status:CapXXX: 0x%016llx]\n", 1ULL<<cap);
} else if (!strncmp("--suggest=", argv[i], 10)) {
cap_value_t cap;
int hits = 0;
for (cap=0; cap < CAPSH_DOC_LIMIT; cap++) {
const char **lines = explanations[cap];
int j;
for (j=0; lines[j]; j++) {
if (strcasestr(lines[j], argv[i]+10) != NULL) {
if (hits++) {
printf("\n");
}
describe(cap);
break;
}
}
}
} else {
usage:
printf("usage: %s [args ...]\n"
@ -1020,6 +1045,7 @@ int main(int argc, char *argv[], char *envp[])
" --print display capability relevant state\n"
" --secbits=<n> write a new value for securebits\n"
" --shell=/xx/yy use /xx/yy instead of " SHELL " for --\n"
" --suggest=text search cap descriptions for text\n"
" --supports=xxx exit 1 if capability xxx unsupported\n"
" --uid=<n> set uid to <n> (hint: id <username>)\n"
" --user=<name> set uid,gid and groups to that of user\n"

View File

@ -41,7 +41,7 @@ static const char *explanation4[] = { /* cap_fsetid = 4 */
NULL
};
static const char *explanation5[] = { /* cap_kill = 5 */
"Allows a process to sent a kill(2) signal to any other",
"Allows a process to send a kill(2) signal to any other",
"process - overriding the limitation that there be a",
"[E]UID match between source and target process.",
NULL