aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-01-24 11:14:20 -0800
committerJorge Lucangeli Obes <jorgelo@google.com>2015-09-03 14:13:03 -0700
commitc2a25909b2c4d989e49cdedcac4dd52c45f0570b (patch)
treea28ef5734c4b09953567398ff90ce4bfce8015d1
parent973e826b0e6a4c9802a10140142f9532a592e8fa (diff)
downloadlibcap-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.c15
-rw-r--r--libcap/libcap.h3
-rw-r--r--progs/capsh.c2
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);