aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-01-24 11:14:20 -0800
committerAndrew G. Morgan <morgan@kernel.org>2008-01-24 11:14:20 -0800
commit97d49fd613d9ceca3f88194fc71e610122f06e8a (patch)
treea6e979702252f36e0d61dc929303785ce04a3a5d
parent4a1c63ec449d03003d06acc313bc2dba4ab561e8 (diff)
downloadlibcap-97d49fd613d9ceca3f88194fc71e610122f06e8a.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);