From 8565668d785d25f6dfd2dd19cece502cedf178b6 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 4 May 2015 12:56:16 -0500 Subject: Implement SELinux ls -Z support. This patch uses lgetfilecon rather than fgetfilecon because dirtree_parentfd always seems to return -1 in this function. If/when the SMACK code is fixed to work with dirtree_parentfd, I'll send a matching patch for SELinux. In the meantime, this works, and although ls -h is still on my to-do list, I think this patch is sufficient to let us replace toolbox ls with toybox ls. --- toys/posix/ls.c | 58 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'toys/posix/ls.c') diff --git a/toys/posix/ls.c b/toys/posix/ls.c index 9c4d6d3b..5dd6bc50 100644 --- a/toys/posix/ls.c +++ b/toys/posix/ls.c @@ -5,7 +5,7 @@ * * See http://opengroup.org/onlinepubs/9699919799/utilities/ls.html -USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")USE_LS_SMACK("Z")"goACFHLRSacdfiklmnpqrstux1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE)) +USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")USE_LS_Z("Z")"goACFHLRSacdfiklmnpqrstux1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE)) config LS bool "ls" @@ -32,10 +32,10 @@ config LS sorting (default is alphabetical): -f unsorted -r reverse -t timestamp -S size -config LS_SMACK +config LS_Z bool default y - depends on LS && TOYBOX_SMACK + depends on LS && (TOYBOX_SELINUX || TOYBOX_SMACK) help usage: ls [-Z] @@ -142,24 +142,42 @@ static int numlen(long long ll) return snprintf(0, 0, "%llu", ll); } -// measure/print smack attributes. (If pad=0, just measure.) -static unsigned zmack(struct dirtree *dt, int pad) +// measure/print SELinux/smack security label. (If pad=0, just measure.) +static unsigned seclabel(struct dirtree *dt, int pad) { - char buf[SMACK_LABEL_LEN+1]; - int fd = openat(dirtree_parentfd(dt), dt->name, O_PATH|O_NOFOLLOW); - ssize_t len = 1; + if (CFG_TOYBOX_SELINUX) { + char* path = dirtree_path(dt, 0); + char* label = 0; + size_t len; + + lgetfilecon(path, &label); + if (!label) { + label = strdup("?"); + } - strcpy(buf, "?"); - if (fd != -1) { - len = fgetxattr(fd, XATTR_NAME_SMACK, pad?buf:0, pad?SMACK_LABEL_LEN:0); - close(fd); + len = strlen(label); + if (pad) printf(" %*s "+(pad>0), pad, label); - if (len<1 || len>SMACK_LABEL_LEN) len = 0; - else buf[len] = 0; - } - if (pad) printf(" %*s "+(pad>0), pad, buf); + free(label); + free(path); + return len; + } else if (CFG_TOYBOX_SMACK) { + int fd = openat(dirtree_parentfd(dt), dt->name, O_PATH|O_NOFOLLOW); + char buf[SMACK_LABEL_LEN+1]; + ssize_t len = 1; + + strcpy(buf, "?"); + if (fd != -1) { + len = fgetxattr(fd, XATTR_NAME_SMACK, pad?buf:0, pad?SMACK_LABEL_LEN:0); + close(fd); + + if (len<1 || len>SMACK_LABEL_LEN) len = 0; + else buf[len] = 0; + } + if (pad) printf(" %*s "+(pad>0), pad, buf); - return len; + return len; + } } // Figure out size of printable entry fields for display indent/wrap @@ -188,7 +206,7 @@ static void entrylen(struct dirtree *dt, unsigned *len) len[6] = (flags & FLAG_s) ? numlen(st->st_blocks) : 0; - if (CFG_LS_SMACK && (flags & FLAG_Z)) len[7] = zmack(dt, 0); + if (CFG_LS_Z && (flags & FLAG_Z)) len[7] = seclabel(dt, 0); } static int compare(void *a, void *b) @@ -437,7 +455,7 @@ static void listfiles(int dirfd, struct dirtree *indir) printf("%s% *ld %s%s%s%s", perm, totals[2]+1, (long)st->st_nlink, usr, upad, grp, grpad); - if (CFG_LS_SMACK && (flags & FLAG_Z)) zmack(sort[next], -(int)totals[7]); + if (CFG_LS_Z && (flags & FLAG_Z)) seclabel(sort[next], -(int)totals[7]); if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) printf("% *d,% 4d", totals[5]-4, major(st->st_rdev),minor(st->st_rdev)); @@ -446,7 +464,7 @@ static void listfiles(int dirfd, struct dirtree *indir) tm = localtime(&(st->st_mtime)); strftime(thyme, sizeof(thyme), "%F %H:%M", tm); xprintf(" %s ", thyme); - } else if (CFG_LS_SMACK && (flags & FLAG_Z)) zmack(sort[next], totals[7]); + } else if (CFG_LS_Z && (flags & FLAG_Z)) seclabel(sort[next], totals[7]); if (flags & FLAG_color) { color = color_from_mode(st->st_mode); -- cgit v1.2.3