aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-05-04 12:56:16 -0500
committerRob Landley <rob@landley.net>2015-05-04 12:56:16 -0500
commit8565668d785d25f6dfd2dd19cece502cedf178b6 (patch)
treeb38a7f663fe71c27ee1ecd2cdf50cbbb4463b4dc
parent483cfdabaf6ab282987a0a21d6177c3daa95dc12 (diff)
downloadtoybox-8565668d785d25f6dfd2dd19cece502cedf178b6.tar.gz
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.
-rw-r--r--toys/posix/ls.c58
1 files changed, 38 insertions, 20 deletions
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);