diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2008-01-24 11:14:20 -0800 |
---|---|---|
committer | Jorge Lucangeli Obes <jorgelo@google.com> | 2015-09-03 14:13:03 -0700 |
commit | c2a25909b2c4d989e49cdedcac4dd52c45f0570b (patch) | |
tree | a28ef5734c4b09953567398ff90ce4bfce8015d1 | |
parent | 973e826b0e6a4c9802a10140142f9532a592e8fa (diff) | |
download | libcap-c2a25909b2c4d989e49cdedcac4dd52c45f0570b.tar.gz |
Fix malloc(size) but in capsh and numeric capabilities (for unnamed bits)
capsh allocated too little memory for the --inh argument - led to glibc
aborting with free().
libcap has always had latent support for identifying unnamed capabilities
with integers. It was untested (and therefore broken) prior to this commit.
Should be fixed now.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | libcap/cap_text.c | 15 | ||||
-rw-r--r-- | libcap/libcap.h | 3 | ||||
-rw-r--r-- | progs/capsh.c | 2 |
3 files changed, 12 insertions, 8 deletions
diff --git a/libcap/cap_text.c b/libcap/cap_text.c index ee22b39..c89e6d6 100644 --- a/libcap/cap_text.c +++ b/libcap/cap_text.c @@ -14,7 +14,7 @@ #include <limits.h> /* Maximum output text length (16 per cap) */ -#define CAP_TEXT_SIZE (16*__CAP_BITS) +#define CAP_TEXT_SIZE (16*__CAP_MAXBITS) #define LIBCAP_EFF 01 #define LIBCAP_INH 02 @@ -72,7 +72,7 @@ static int lookupname(char const **strp) str.constp = *strp; if (isdigit(*str.constp)) { unsigned long n = strtoul(str.constp, &str.p, 0); - if (n >= __CAP_BITS) + if (n >= __CAP_MAXBITS) return -1; *strp = str.constp; return n; @@ -290,7 +290,8 @@ char *cap_to_text(cap_t caps, ssize_t *length_p) static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE]; char *p; int histo[8] = {0}; - int m, n, t; + int m, t; + unsigned n; /* Check arguments */ if (!good_cap_t(caps)) { @@ -302,7 +303,7 @@ char *cap_to_text(cap_t caps, ssize_t *length_p) _cap_debugcap("i = ", *caps, CAP_INHERITABLE); _cap_debugcap("p = ", *caps, CAP_PERMITTED); - for (n = __CAP_BITS; n--; ) + for (n = __CAP_MAXBITS; n--; ) histo[getstateflags(caps, n)]++; for (m=t=7; t--; ) @@ -318,12 +319,12 @@ char *cap_to_text(cap_t caps, ssize_t *length_p) for (t = 8; t--; ) if (t != m && histo[t]) { *p++ = ' '; - for (n = 0; n != __CAP_BITS; n++) + for (n = 0; n < __CAP_MAXBITS; n++) if (getstateflags(caps, n) == t) { - if (_cap_names[n]) + if (n < __CAP_BITS) p += sprintf(p, "%s,", _cap_names[n]); else - p += sprintf(p, "%d,", n); + p += sprintf(p, "%u,", n); if (p - buf > CAP_TEXT_SIZE) { errno = ERANGE; return NULL; diff --git a/libcap/libcap.h b/libcap/libcap.h index 854f907..bd22397 100644 --- a/libcap/libcap.h +++ b/libcap/libcap.h @@ -98,6 +98,9 @@ struct _cap_struct { } u[_LINUX_CAPABILITY_U32S]; }; +/* the maximum bits supportable */ +#define __CAP_MAXBITS (__CAP_BLKS * 32) + /* string magic for cap_free */ #define CAP_S_MAGIC 0xCA95D0 diff --git a/progs/capsh.c b/progs/capsh.c index 278bb17..13ccf46 100644 --- a/progs/capsh.c +++ b/progs/capsh.c @@ -108,7 +108,7 @@ int main(int argc, char *argv[], char *envp[]) perror("Fatal error concerning process capabilities"); exit(1); } - ptr = malloc(4 + strlen(argv[i]+6) + strlen(text)); + ptr = malloc(10 + strlen(argv[i]+6) + strlen(text)); if (ptr == NULL) { perror("Out of memory for inh set\n"); exit(1); |