selinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> (HitachiSoft)

This commit is contained in:
Denis Vlasenko 2007-03-10 16:58:49 +00:00
parent 4eb8b936cb
commit 49622d7846
14 changed files with 452 additions and 47 deletions

View File

@ -3,6 +3,7 @@
* Mini cp implementation for busybox * Mini cp implementation for busybox
* *
* Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
* SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
* *
* Licensed under GPL v2 or later, see file LICENSE in this tarball for details. * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
*/ */
@ -50,6 +51,12 @@ int cp_main(int argc, char **argv)
if (flags & OPT_H) ... // deref command-line params only if (flags & OPT_H) ... // deref command-line params only
*/ */
#if ENABLE_SELINUX
if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) {
selinux_or_die();
}
#endif
flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */
if (optind + 2 > argc) { if (optind + 2 > argc) {

View File

@ -10,6 +10,7 @@
/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
/* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
* be more similar to GNU id. * be more similar to GNU id.
* -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
*/ */
#include "busybox.h" #include "busybox.h"
@ -17,14 +18,13 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef CONFIG_SELINUX
#include <selinux/selinux.h> /* for is_selinux_enabled() */
#endif
#define PRINT_REAL 1 #define PRINT_REAL 1
#define NAME_NOT_NUMBER 2 #define NAME_NOT_NUMBER 2
#define JUST_USER 4 #define JUST_USER 4
#define JUST_GROUP 8 #define JUST_GROUP 8
#if ENABLE_SELINUX
#define JUST_CONTEXT 16
#endif
static short printf_full(unsigned int id, const char *arg, const char prefix) static short printf_full(unsigned int id, const char *arg, const char prefix)
{ {
@ -47,11 +47,13 @@ int id_main(int argc, char **argv)
gid_t gid; gid_t gid;
unsigned long flags; unsigned long flags;
short status; short status;
#if ENABLE_SELINUX
security_context_t scontext;
#endif
/* Don't allow -n -r -nr -ug -rug -nug -rnug */ /* Don't allow -n -r -nr -ug -rug -nug -rnug */
/* Don't allow more than one username */ /* Don't allow more than one username */
opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug"; opt_complementary = "?1:?:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g");
flags = getopt32(argc, argv, "rnug"); flags = getopt32(argc, argv, "rnug" USE_SELINUX("Z"));
/* This values could be overwritten later */ /* This values could be overwritten later */
uid = geteuid(); uid = geteuid();
@ -69,14 +71,33 @@ int id_main(int argc, char **argv)
/* in this case PRINT_REAL is the same */ /* in this case PRINT_REAL is the same */
} }
if (flags & (JUST_GROUP | JUST_USER)) { if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
/* JUST_GROUP and JUST_USER are mutually exclusive */ /* JUST_GROUP and JUST_USER are mutually exclusive */
if (flags & NAME_NOT_NUMBER) { if (flags & NAME_NOT_NUMBER) {
/* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */
puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 ));
} else { } else {
printf("%u\n", (flags & JUST_USER) ? uid : gid); if (flags & JUST_USER) {
printf("%u\n", uid);
} }
if (flags & JUST_GROUP) {
printf("%u\n", gid);
}
}
#if ENABLE_SELINUX
if (flags & JUST_CONTEXT) {
selinux_or_die();
if (argc - optind == 1) {
bb_error_msg_and_die("can't print security context when user specified");
}
if (getcon(&scontext)) {
bb_error_msg_and_die("can't get process context");
}
printf("%s\n", scontext);
}
#endif
/* exit */ /* exit */
fflush_stdout_and_exit(EXIT_SUCCESS); fflush_stdout_and_exit(EXIT_SUCCESS);
} }
@ -88,7 +109,7 @@ int id_main(int argc, char **argv)
/* bb_getgrgid doesn't exit on failure here */ /* bb_getgrgid doesn't exit on failure here */
status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); status |= printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g');
#ifdef CONFIG_SELINUX #if ENABLE_SELINUX
if (is_selinux_enabled()) { if (is_selinux_enabled()) {
security_context_t mysid; security_context_t mysid;
const char *context; const char *context;

View File

@ -21,10 +21,49 @@ static const struct option install_long_options[] = {
{ "group", 0, NULL, 'g' }, { "group", 0, NULL, 'g' },
{ "mode", 0, NULL, 'm' }, { "mode", 0, NULL, 'm' },
{ "owner", 0, NULL, 'o' }, { "owner", 0, NULL, 'o' },
#if ENABLE_SELINUX
{ "context", 1, NULL, 'Z' },
{ "preserve_context", 0, NULL, 0xff },
{ "preserve-context", 0, NULL, 0xff },
#endif
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
#endif #endif
#if ENABLE_SELINUX
static bool use_default_selinux_context = 1;
static void setdefaultfilecon(const char *path) {
struct stat s;
security_context_t scontext = NULL;
if (!is_selinux_enabled()) {
return;
}
if (lstat(path, &s) != 0) {
return;
}
if (matchpathcon(path, s.st_mode, &scontext) < 0) {
goto out;
}
if (strcmp(scontext, "<<none>>") == 0) {
goto out;
}
if (lsetfilecon(path, scontext) < 0) {
if (errno != ENOTSUP) {
bb_perror_msg("warning: failed to change context of %s to %s", path, scontext);
}
}
out:
freecon(scontext);
}
#endif
int install_main(int argc, char **argv); int install_main(int argc, char **argv);
int install_main(int argc, char **argv) int install_main(int argc, char **argv)
{ {
@ -37,7 +76,9 @@ int install_main(int argc, char **argv)
const char *mode_str; const char *mode_str;
int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
int ret = EXIT_SUCCESS, flags, i, isdir; int ret = EXIT_SUCCESS, flags, i, isdir;
#if ENABLE_SELINUX
security_context_t scontext;
#endif
enum { enum {
OPT_CMD = 0x1, OPT_CMD = 0x1,
OPT_DIRECTORY = 0x2, OPT_DIRECTORY = 0x2,
@ -46,14 +87,35 @@ int install_main(int argc, char **argv)
OPT_GROUP = 0x10, OPT_GROUP = 0x10,
OPT_MODE = 0x20, OPT_MODE = 0x20,
OPT_OWNER = 0x40, OPT_OWNER = 0x40,
#if ENABLE_SELINUX
OPT_SET_SECURITY_CONTEXT = 0x80,
OPT_PRESERVE_SECURITY_CONTEXT = 0x100,
#endif
}; };
#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
applet_long_options = install_long_options; applet_long_options = install_long_options;
#endif #endif
opt_complementary = "?:s--d:d--s"; opt_complementary = "?:s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z");
/* -c exists for backwards compatibility, its needed */ /* -c exists for backwards compatibility, it's needed */
flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str);
flags = getopt32(argc, argv, "cdpsg:m:o:" USE_SELINUX("Z:"), &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext));
#if ENABLE_SELINUX
if (flags & OPT_PRESERVE_SECURITY_CONTEXT) {
use_default_selinux_context = 0;
copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
selinux_or_die();
}
if (flags & OPT_SET_SECURITY_CONTEXT) {
selinux_or_die();
if (setfscreatecon(scontext) < 0) {
bb_error_msg_and_die("setfscreatecon(%s)", scontext); // perror?
}
use_default_selinux_context = 0;
copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT;
}
#endif
/* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */
if (flags & OPT_PRESERVE_TIME) { if (flags & OPT_PRESERVE_TIME) {
@ -117,7 +179,10 @@ int install_main(int argc, char **argv)
bb_perror_msg("cannot change permissions of %s", dest); bb_perror_msg("cannot change permissions of %s", dest);
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} }
#if ENABLE_SELINUX
if (use_default_selinux_context)
setdefaultfilecon(dest);
#endif
/* Set the user and group id */ /* Set the user and group id */
if ((flags & (OPT_OWNER|OPT_GROUP)) if ((flags & (OPT_OWNER|OPT_GROUP))
&& lchown(dest, uid, gid) == -1 && lchown(dest, uid, gid) == -1

View File

@ -30,11 +30,25 @@ mode_t getopt_mk_fifo_nod(int argc, char **argv)
{ {
mode_t mode = 0666; mode_t mode = 0666;
char *smode = NULL; char *smode = NULL;
#if ENABLE_SELINUX
getopt32(argc, argv, "m:", &smode); security_context_t scontext;
if(smode) { #endif
int opt;
opt = getopt32(argc, argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
if (opt & 1) {
if (bb_parse_mode(smode, &mode)) if (bb_parse_mode(smode, &mode))
umask(0); umask(0);
} }
#if ENABLE_SELINUX
if (opt & 2) {
selinux_or_die();
if (setfscreatecon(scontext)) {
bb_error_msg_and_die("cannot set default file creation context "
"to %s", scontext);
}
}
#endif
return mode; return mode;
} }

View File

@ -716,7 +716,8 @@ static const char ls_options[] = "Cadil1gnsxAk"
USE_FEATURE_LS_RECURSIVE("R") USE_FEATURE_LS_RECURSIVE("R")
USE_FEATURE_HUMAN_READABLE("h") USE_FEATURE_HUMAN_READABLE("h")
USE_SELINUX("K") USE_SELINUX("K")
USE_FEATURE_AUTOWIDTH("T:w:"); USE_FEATURE_AUTOWIDTH("T:w:")
USE_SELINUX("Z");
enum { enum {
LIST_MASK_TRIGGER = 0, LIST_MASK_TRIGGER = 0,
@ -768,6 +769,9 @@ static const unsigned opt_flags[] = {
#endif #endif
#if ENABLE_FEATURE_AUTOWIDTH #if ENABLE_FEATURE_AUTOWIDTH
0, 0, /* T, w - ignored */ 0, 0, /* T, w - ignored */
#endif
#if ENABLE_SELINUX
LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */
#endif #endif
(1U<<31) (1U<<31)
}; };

View File

@ -16,6 +16,9 @@
* conjunction with -m. * conjunction with -m.
*/ */
/* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support.
*/
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h> /* struct option */ #include <getopt.h> /* struct option */
@ -25,6 +28,9 @@
static const struct option mkdir_long_options[] = { static const struct option mkdir_long_options[] = {
{ "mode", 1, NULL, 'm' }, { "mode", 1, NULL, 'm' },
{ "parents", 0, NULL, 'p' }, { "parents", 0, NULL, 'p' },
#if ENABLE_SELINUX
{ "context", 1, NULL, 'Z' },
#endif
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
#endif #endif
@ -37,11 +43,14 @@ int mkdir_main(int argc, char **argv)
int flags = 0; int flags = 0;
unsigned opt; unsigned opt;
char *smode; char *smode;
#if ENABLE_SELINUX
security_context_t scontext;
#endif
#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
applet_long_options = mkdir_long_options; applet_long_options = mkdir_long_options;
#endif #endif
opt = getopt32(argc, argv, "m:p", &smode); opt = getopt32(argc, argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
if (opt & 1) { if (opt & 1) {
mode = 0777; mode = 0777;
if (!bb_parse_mode(smode, &mode)) { if (!bb_parse_mode(smode, &mode)) {
@ -50,6 +59,15 @@ int mkdir_main(int argc, char **argv)
} }
if (opt & 2) if (opt & 2)
flags |= FILEUTILS_RECUR; flags |= FILEUTILS_RECUR;
#if ENABLE_SELINUX
if (opt & 4) {
selinux_or_die();
if (setfscreatecon(scontext)) {
bb_error_msg_and_die("cannot set default file creation context "
"to %s", scontext);
}
}
#endif
if (optind == argc) { if (optind == argc) {
bb_show_usage(); bb_show_usage();

View File

@ -3,6 +3,7 @@
* Mini mv implementation for busybox * Mini mv implementation for busybox
* *
* Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
* SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
* *
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/ */
@ -44,6 +45,7 @@ int mv_main(int argc, char **argv)
unsigned long flags; unsigned long flags;
int dest_exists; int dest_exists;
int status = 0; int status = 0;
int copy_flag = 0;
#if ENABLE_FEATURE_MV_LONG_OPTIONS #if ENABLE_FEATURE_MV_LONG_OPTIONS
applet_long_options = mv_long_options; applet_long_options = mv_long_options;
@ -113,8 +115,11 @@ DO_MOVE:
goto RET_1; goto RET_1;
} }
} }
if ((copy_file(*argv, dest, copy_flag = FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS;
FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) && #if ENABLE_SELINUX
copy_flag |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
#endif
if ((copy_file(*argv, dest, copy_flag) >= 0) &&
(remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) { (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) {
goto RET_0; goto RET_0;
} }

View File

@ -5,6 +5,7 @@
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation. * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
* Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
* Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
* Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp>
* *
* Written by Michael Meskes * Written by Michael Meskes
* Taken from coreutils and turned into a busybox applet by Mike Frysinger * Taken from coreutils and turned into a busybox applet by Mike Frysinger
@ -17,6 +18,7 @@
/* vars to control behavior */ /* vars to control behavior */
#define OPT_TERSE 2 #define OPT_TERSE 2
#define OPT_DEREFERENCE 4 #define OPT_DEREFERENCE 4
#define OPT_SELINUX 8
static long flags; static long flags;
static char const *file_type(struct stat const *st) static char const *file_type(struct stat const *st)
@ -114,7 +116,8 @@ static char const *human_fstype(long f_type)
#ifdef CONFIG_FEATURE_STAT_FORMAT #ifdef CONFIG_FEATURE_STAT_FORMAT
/* print statfs info */ /* print statfs info */
static void print_statfs(char *pformat, size_t buf_len, char m, static void print_statfs(char *pformat, size_t buf_len, char m,
char const *filename, void const *data) char const *filename, void const *data
USE_SELINUX(,security_context_t scontext) )
{ {
struct statfs const *statfsbuf = data; struct statfs const *statfsbuf = data;
@ -164,6 +167,14 @@ static void print_statfs(char *pformat, size_t buf_len, char m,
strncat(pformat, "jd", buf_len); strncat(pformat, "jd", buf_len);
printf(pformat, (intmax_t) (statfsbuf->f_ffree)); printf(pformat, (intmax_t) (statfsbuf->f_ffree));
break; break;
#if ENABLE_SELINUX
case 'C':
if (flags & OPT_SELINUX) {
strncat(pformat, "s", buf_len);
printf(scontext);
}
break;
#endif
default: default:
strncat(pformat, "c", buf_len); strncat(pformat, "c", buf_len);
printf(pformat, m); printf(pformat, m);
@ -173,7 +184,8 @@ static void print_statfs(char *pformat, size_t buf_len, char m,
/* print stat info */ /* print stat info */
static void print_stat(char *pformat, size_t buf_len, char m, static void print_stat(char *pformat, size_t buf_len, char m,
char const *filename, void const *data) char const *filename, void const *data
USE_SELINUX(, security_context_t scontext))
{ {
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
struct stat *statbuf = (struct stat *) data; struct stat *statbuf = (struct stat *) data;
@ -301,6 +313,14 @@ static void print_stat(char *pformat, size_t buf_len, char m,
strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
printf(pformat, (unsigned long int) statbuf->st_ctime); printf(pformat, (unsigned long int) statbuf->st_ctime);
break; break;
#if ENABLE_SELINUX
case 'C':
if (flags & OPT_SELINUX) {
strncat(pformat, "s", buf_len);
printf(pformat, scontext);
}
break;
#endif
default: default:
strncat(pformat, "c", buf_len); strncat(pformat, "c", buf_len);
printf(pformat, m); printf(pformat, m);
@ -309,8 +329,9 @@ static void print_stat(char *pformat, size_t buf_len, char m,
} }
static void print_it(char const *masterformat, char const *filename, static void print_it(char const *masterformat, char const *filename,
void (*print_func) (char *, size_t, char, char const *, void const *), void (*print_func) (char *, size_t, char, char const *, void const *
void const *data) USE_SELINUX(, security_context_t scontext)),
void const *data USE_SELINUX(, security_context_t scontext) )
{ {
char *b; char *b;
@ -350,7 +371,7 @@ static void print_it(char const *masterformat, char const *filename,
putchar('%'); putchar('%');
break; break;
default: default:
print_func(dest, n_alloc, *p, filename, data); print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext));
break; break;
} }
} }
@ -365,6 +386,16 @@ static int do_statfs(char const *filename, char const *format)
{ {
struct statfs statfsbuf; struct statfs statfsbuf;
#if ENABLE_SELINUX
security_context_t scontext = NULL;
if (flags & OPT_SELINUX) {
if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext):
getfilecon(filename, scontext))< 0) {
bb_perror_msg(filename);
return 0;
}
}
#endif
if (statfs(filename, &statfsbuf) != 0) { if (statfs(filename, &statfsbuf) != 0) {
bb_perror_msg("cannot read file system information for '%s'", filename); bb_perror_msg("cannot read file system information for '%s'", filename);
return 0; return 0;
@ -372,6 +403,7 @@ static int do_statfs(char const *filename, char const *format)
#ifdef CONFIG_FEATURE_STAT_FORMAT #ifdef CONFIG_FEATURE_STAT_FORMAT
if (format == NULL) if (format == NULL)
#ifndef ENABLE_SELINUX
format = (flags & OPT_TERSE format = (flags & OPT_TERSE
? "%n %i %l %t %s %b %f %a %c %d\n" ? "%n %i %l %t %s %b %f %a %c %d\n"
: " File: \"%n\"\n" : " File: \"%n\"\n"
@ -379,9 +411,27 @@ static int do_statfs(char const *filename, char const *format)
"Block size: %-10s\n" "Block size: %-10s\n"
"Blocks: Total: %-10b Free: %-10f Available: %a\n" "Blocks: Total: %-10b Free: %-10f Available: %a\n"
"Inodes: Total: %-10c Free: %d"); "Inodes: Total: %-10c Free: %d");
print_it(format, filename, print_statfs, &statfsbuf); print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
#else #else
format = (flags & OPT_TERSE
? (flags & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n":
"%n %i %l %t %s %b %f %a %c %d\n")
: (flags & OPT_SELINUX ?
" File: \"%n\"\n"
" ID: %-8i Namelen: %-7l Type: %T\n"
"Block size: %-10s\n"
"Blocks: Total: %-10b Free: %-10f Available: %a\n"
"Inodes: Total: %-10c Free: %d"
" S_context: %C\n":
" File: \"%n\"\n"
" ID: %-8i Namelen: %-7l Type: %T\n"
"Block size: %-10s\n"
"Blocks: Total: %-10b Free: %-10f Available: %a\n"
"Inodes: Total: %-10c Free: %d\n")
);
print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
#endif /* SELINUX */
#else /* FEATURE_STAT_FORMAT */
format = (flags & OPT_TERSE format = (flags & OPT_TERSE
? "%s %llx %lu " ? "%s %llx %lu "
: " File: \"%s\"\n" : " File: \"%s\"\n"
@ -396,6 +446,7 @@ static int do_statfs(char const *filename, char const *format)
else else
printf("Type: %s\n", human_fstype(statfsbuf.f_type)); printf("Type: %s\n", human_fstype(statfsbuf.f_type));
#if !ENABLE_SELINUX
format = (flags & OPT_TERSE format = (flags & OPT_TERSE
? "%lu %ld %ld %ld %ld %ld\n" ? "%lu %ld %ld %ld %ld %ld\n"
: "Block size: %-10lu\n" : "Block size: %-10lu\n"
@ -408,8 +459,31 @@ static int do_statfs(char const *filename, char const *format)
(intmax_t) (statfsbuf.f_bavail), (intmax_t) (statfsbuf.f_bavail),
(intmax_t) (statfsbuf.f_files), (intmax_t) (statfsbuf.f_files),
(intmax_t) (statfsbuf.f_ffree)); (intmax_t) (statfsbuf.f_ffree));
#endif #else
format = (flags & OPT_TERSE
? (flags & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n":
"%lu %ld %ld %ld %ld %ld\n")
: (flags & OPT_SELINUX ?
"Block size: %-10lu\n"
"Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
"Inodes: Total: %-10jd Free: %jd"
"S_context: %C\n":
"Block size: %-10lu\n"
"Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
"Inodes: Total: %-10jd Free: %jd\n"));
printf(format,
(unsigned long int) (statfsbuf.f_bsize),
(intmax_t) (statfsbuf.f_blocks),
(intmax_t) (statfsbuf.f_bfree),
(intmax_t) (statfsbuf.f_bavail),
(intmax_t) (statfsbuf.f_files),
(intmax_t) (statfsbuf.f_ffree),
scontext);
if (scontext)
freecon(scontext);
#endif
#endif /* FEATURE_STAT_FORMAT */
return 1; return 1;
} }
@ -417,7 +491,16 @@ static int do_statfs(char const *filename, char const *format)
static int do_stat(char const *filename, char const *format) static int do_stat(char const *filename, char const *format)
{ {
struct stat statbuf; struct stat statbuf;
#if ENABLE_SELINUX
security_context_t scontext = NULL;
if (flags & OPT_SELINUX) {
if ((flags & OPT_DEREFERENCE ? lgetfilecon(filename, scontext):
getfilecon(filename, scontext))< 0) {
bb_perror_msg (filename);
return 0;
}
}
#endif
if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) {
bb_perror_msg("cannot stat '%s'", filename); bb_perror_msg("cannot stat '%s'", filename);
return 0; return 0;
@ -425,6 +508,7 @@ static int do_stat(char const *filename, char const *format)
#ifdef CONFIG_FEATURE_STAT_FORMAT #ifdef CONFIG_FEATURE_STAT_FORMAT
if (format == NULL) { if (format == NULL) {
#ifndef ENABLE_SELINUX
if (flags & OPT_TERSE) { if (flags & OPT_TERSE) {
format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
} else { } else {
@ -445,11 +529,49 @@ static int do_stat(char const *filename, char const *format)
"Access: %x\n" "Modify: %y\n" "Change: %z\n"; "Access: %x\n" "Modify: %y\n" "Change: %z\n";
} }
} }
}
print_it(format, filename, print_stat, &statbuf);
#else #else
if (flags & OPT_TERSE) { if (flags & OPT_TERSE) {
printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu\n", format = (flags & OPT_SELINUX ?
"%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n":
"%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n");
} else {
if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
format = (flags & OPT_SELINUX ?
" File: \"%N\"\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %-5h"
" Device type: %t,%T\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
" S_Context: %C\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n":
" File: \"%N\"\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %-5h"
" Device type: %t,%T\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n");
} else {
format = (flags & OPT_SELINUX ?
" File: \"%N\"\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %h\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
"S_Context: %C\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n":
" File: \"%N\"\n"
" Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
"Device: %Dh/%dd\tInode: %-10i Links: %h\n"
"Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
"Access: %x\n" "Modify: %y\n" "Change: %z\n");
}
}
#endif
}
print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext));
#else /* FEATURE_STAT_FORMAT */
if (flags & OPT_TERSE) {
printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu"
SKIP_SELINUX("\n"),
filename, filename,
(uintmax_t) (statbuf.st_size), (uintmax_t) (statbuf.st_size),
(uintmax_t) statbuf.st_blocks, (uintmax_t) statbuf.st_blocks,
@ -466,6 +588,12 @@ static int do_stat(char const *filename, char const *format)
(unsigned long int) statbuf.st_ctime, (unsigned long int) statbuf.st_ctime,
(unsigned long int) statbuf.st_blksize (unsigned long int) statbuf.st_blksize
); );
#if ENABLE_SELINUX
if (flags & OPT_SELINUX)
printf(" %lc\n", *scontext);
else
putchar('\n');
#endif
} else { } else {
char *linkname = NULL; char *linkname = NULL;
@ -499,19 +627,22 @@ static int do_stat(char const *filename, char const *format)
(unsigned long int) minor(statbuf.st_rdev)); (unsigned long int) minor(statbuf.st_rdev));
else else
putchar('\n'); putchar('\n');
printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n" printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n",
"Access: %s\n" "Modify: %s\n" "Change: %s\n",
(unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
bb_mode_string(statbuf.st_mode), bb_mode_string(statbuf.st_mode),
(unsigned long int) statbuf.st_uid, (unsigned long int) statbuf.st_uid,
(pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN", (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
(unsigned long int) statbuf.st_gid, (unsigned long int) statbuf.st_gid,
(gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN", (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
#if ENABLE_SELINUX
printf(" S_Context: %lc\n", *scontext);
#endif
printf("Access: %s\n" "Modify: %s\n" "Change: %s\n",
human_time(statbuf.st_atime), human_time(statbuf.st_atime),
human_time(statbuf.st_mtime), human_time(statbuf.st_mtime),
human_time(statbuf.st_ctime)); human_time(statbuf.st_ctime));
} }
#endif #endif /* FEATURE_STAT_FORMAT */
return 1; return 1;
} }
@ -524,6 +655,7 @@ int stat_main(int argc, char **argv)
int (*statfunc)(char const *, char const *) = do_stat; int (*statfunc)(char const *, char const *) = do_stat;
flags = getopt32(argc, argv, "ftL" flags = getopt32(argc, argv, "ftL"
USE_SELINUX("Z")
USE_FEATURE_STAT_FORMAT("c:", &format) USE_FEATURE_STAT_FORMAT("c:", &format)
); );
@ -532,6 +664,11 @@ int stat_main(int argc, char **argv)
if (argc == optind) /* files */ if (argc == optind) /* files */
bb_show_usage(); bb_show_usage();
#if ENABLE_SELINUX
if (flags & OPT_SELINUX) {
selinux_or_die();
}
#endif /* ENABLE_SELINUX */
for (i = optind; i < argc; ++i) for (i = optind; i < argc; ++i)
ok &= statfunc(argv[i], format); ok &= statfunc(argv[i], format);

View File

@ -69,6 +69,7 @@ USE_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_CAT(APPLET(cat, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CAT(APPLET(cat, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_CHATTR(APPLET(chattr, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CHATTR(APPLET(chattr, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_CHCON(APPLET(chcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_CHGRP(APPLET(chgrp, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CHGRP(APPLET(chgrp, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_CHMOD(APPLET(chmod, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CHMOD(APPLET(chmod, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_CHOWN(APPLET(chown, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_CHOWN(APPLET(chown, _BB_DIR_BIN, _BB_SUID_NEVER))
@ -249,6 +250,7 @@ USE_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)) USE_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts))
USE_RUNCON(APPLET(runcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_RUNLEVEL(APPLET(runlevel, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_RUNLEVEL(APPLET(runlevel, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_RUNSV(APPLET(runsv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_RUNSV(APPLET(runsv, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER))

View File

@ -742,7 +742,7 @@ void *md5_end(void *resbuf, md5_ctx_t *ctx);
uint32_t *crc32_filltable(int endian); uint32_t *crc32_filltable(int endian);
enum { /* DO NOT CHANGE THESE VALUES! cp.c depends on them. */ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */
FILEUTILS_PRESERVE_STATUS = 1, FILEUTILS_PRESERVE_STATUS = 1,
FILEUTILS_DEREFERENCE = 2, FILEUTILS_DEREFERENCE = 2,
FILEUTILS_RECUR = 4, FILEUTILS_RECUR = 4,
@ -750,9 +750,13 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c depends on them. */
FILEUTILS_INTERACTIVE = 0x10, FILEUTILS_INTERACTIVE = 0x10,
FILEUTILS_MAKE_HARDLINK = 0x20, FILEUTILS_MAKE_HARDLINK = 0x20,
FILEUTILS_MAKE_SOFTLINK = 0x40, FILEUTILS_MAKE_SOFTLINK = 0x40,
#if ENABLE_SELINUX
FILEUTILS_PRESERVE_SECURITY_CONTEXT = 0x80,
FILEUTILS_SET_SECURITY_CONTEXT = 0x100
#endif
}; };
#define FILEUTILS_CP_OPTSTR "pdRfils"
#define FILEUTILS_CP_OPTSTR "pdRfils" USE_SELINUX("c")
extern const char *applet_name; extern const char *applet_name;
extern const char BB_BANNER[]; extern const char BB_BANNER[];

View File

@ -198,6 +198,24 @@
" -R Recursively list subdirectories\n" \ " -R Recursively list subdirectories\n" \
" -v Set the file's version/generation number" " -v Set the file's version/generation number"
#define chcon_trivial_usage \
"[OPTIONS] CONTEXT FILE...\n" \
" chcon [OPTIONS] [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n" \
" chcon [OPTIONS] --reference=RFILE FILE...\n"
#define chcon_full_usage \
"Change the security context of each FILE to CONTEXT\n\n" \
" -c, --changes Like verbose but report only when a change is made\n" \
" -h, --no-dereference Affect symbolic links instead of any referenced file\n" \
" (available only on systems with lchown system call)\n" \
" -f, --silent, --quiet Suppress most error messages\n" \
" --reference=RFILE Use RFILE's group instead of using a CONTEXT value\n" \
" -u, --user=USER Set user USER in the target security context\n" \
" -r, --role=ROLE Set role ROLE in the target security context\n" \
" -t, --type=TYPE Set type TYPE in the target security context\n" \
" -l, --range=RANGE Set range RANGE in the target security context\n" \
" -R, --recursive Recurse subdirs\n" \
" -v, --verbose Verbose mode" \
#define chgrp_trivial_usage \ #define chgrp_trivial_usage \
"[-Rh"USE_DESKTOP("cvf")"]... GROUP FILE..." "[-Rh"USE_DESKTOP("cvf")"]... GROUP FILE..."
#define chgrp_full_usage \ #define chgrp_full_usage \
@ -404,6 +422,9 @@
"Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY" \ "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY" \
"\n\nOptions:\n" \ "\n\nOptions:\n" \
" -a Same as -dpR\n" \ " -a Same as -dpR\n" \
USE_SELINUX( \
" -c Preserves security context\n" \
) \
" -d,-P Preserve links\n" \ " -d,-P Preserve links\n" \
" -H,-L Dereference all symlinks (implied by default)\n" \ " -H,-L Dereference all symlinks (implied by default)\n" \
" -p Preserve file attributes if possible\n" \ " -p Preserve file attributes if possible\n" \
@ -1321,7 +1342,8 @@
"Print information for USERNAME or the current user" \ "Print information for USERNAME or the current user" \
"\n\nOptions:\n" \ "\n\nOptions:\n" \
USE_SELINUX( \ USE_SELINUX( \
" -c Prints only the security context\n") \ " -Z prints only the security context\n" \
) \
" -g Prints only the group ID\n" \ " -g Prints only the group ID\n" \
" -u Prints only the user ID\n" \ " -u Prints only the user ID\n" \
" -n Print a name instead of a number\n" \ " -n Print a name instead of a number\n" \
@ -1540,7 +1562,10 @@
" -m Set permission modes\n" \ " -m Set permission modes\n" \
" -o Set ownership\n" \ " -o Set ownership\n" \
" -p Preserve date\n" \ " -p Preserve date\n" \
" -s Strip symbol tables" " -s Strip symbol tables" \
USE_SELINUX( \
"\n -Z Set security context of copy" \
)
#define ip_trivial_usage \ #define ip_trivial_usage \
"[OPTIONS] {address | link | route | tunnel | rule} {COMMAND}" "[OPTIONS] {address | link | route | tunnel | rule} {COMMAND}"
@ -1850,7 +1875,9 @@
USE_SELINUX( \ USE_SELINUX( \
"\n -k Print security context") \ "\n -k Print security context") \
USE_SELINUX( \ USE_SELINUX( \
"\n -K Print security context in long format") "\n -K Print security context in long format") \
USE_SELINUX( \
"\n -Z Print security context and permission")
#define lsattr_trivial_usage \ #define lsattr_trivial_usage \
"[-Radlv] [files...]" "[-Radlv] [files...]"
@ -1995,7 +2022,11 @@
"Create the DIRECTORY(ies) if they do not already exist" \ "Create the DIRECTORY(ies) if they do not already exist" \
"\n\nOptions:\n" \ "\n\nOptions:\n" \
" -m Set permission mode (as in chmod), not rwxrwxrwx - umask\n" \ " -m Set permission mode (as in chmod), not rwxrwxrwx - umask\n" \
" -p No error if existing, make parent directories as needed" " -p No error if existing, make parent directories as needed" \
USE_SELINUX( \
"\n -Z Set security context" \
)
#define mkdir_example_usage \ #define mkdir_example_usage \
"$ mkdir /tmp/foo\n" \ "$ mkdir /tmp/foo\n" \
"$ mkdir /tmp/foo\n" \ "$ mkdir /tmp/foo\n" \
@ -2040,7 +2071,10 @@
#define mkfifo_full_usage \ #define mkfifo_full_usage \
"Create a named pipe (identical to 'mknod name p')" \ "Create a named pipe (identical to 'mknod name p')" \
"\n\nOptions:\n" \ "\n\nOptions:\n" \
" -m Create the pipe using the specified mode (default a=rw)" " -m Create the pipe using the specified mode (default a=rw)" \
USE_SELINUX( \
"\n -Z Set security context" \
)
#define mkfs_minix_trivial_usage \ #define mkfs_minix_trivial_usage \
"[-c | -l filename] [-nXX] [-iXX] /dev/name [blocks]" "[-c | -l filename] [-nXX] [-iXX] /dev/name [blocks]"
@ -2062,7 +2096,11 @@
"\n\nTYPEs include:\n" \ "\n\nTYPEs include:\n" \
" b: Make a block (buffered) device\n" \ " b: Make a block (buffered) device\n" \
" c or u: Make a character (un-buffered) device\n" \ " c or u: Make a character (un-buffered) device\n" \
" p: Make a named pipe. MAJOR and MINOR are ignored for named pipes" " p: Make a named pipe. MAJOR and MINOR are ignored for named pipes" \
USE_SELINUX( \
"\n -Z Set security context" \
)
#define mknod_example_usage \ #define mknod_example_usage \
"$ mknod /dev/fd0 b 2 0\n" \ "$ mknod /dev/fd0 b 2 0\n" \
"$ mknod -m 644 /tmp/pipe p\n" "$ mknod -m 644 /tmp/pipe p\n"
@ -2698,6 +2736,20 @@
#define rpm2cpio_full_usage \ #define rpm2cpio_full_usage \
"Output a cpio archive of the rpm file" "Output a cpio archive of the rpm file"
#define runcon_trivial_usage \
"[-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n" \
" runcon CONTEXT COMMAND [args]"
#define runcon_full_usage \
"runcon [-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n" \
"runcon CONTEXT COMMAND [args]\n" \
"Run a program in a different security context\n\n" \
" CONTEXT Complete security context\n" \
" -c, --compute Compute process transition context before modifying\n" \
" -t, --type=TYPE Type (for same role as parent)\n" \
" -u, --user=USER User identity\n" \
" -r, --role=ROLE Role\n" \
" -l, --range=RNG Levelrange" \
#define run_parts_trivial_usage \ #define run_parts_trivial_usage \
"[-t] [-a ARG] [-u MASK] DIRECTORY" "[-t] [-a ARG] [-u MASK] DIRECTORY"
#define run_parts_full_usage \ #define run_parts_full_usage \
@ -2924,6 +2976,9 @@
" -f Display filesystem status\n" \ " -f Display filesystem status\n" \
" -L,-l Dereference links\n" \ " -L,-l Dereference links\n" \
" -t Display info in terse form" \ " -t Display info in terse form" \
USE_SELINUX( \
"\n -Z Print security context" \
) \
USE_FEATURE_STAT_FORMAT( \ USE_FEATURE_STAT_FORMAT( \
"\n\nValid format sequences for files:\n" \ "\n\nValid format sequences for files:\n" \
" %a Access rights in octal\n" \ " %a Access rights in octal\n" \
@ -2958,6 +3013,9 @@
" %c Total file nodes in file system\n" \ " %c Total file nodes in file system\n" \
" %d Free file nodes in file system\n" \ " %d Free file nodes in file system\n" \
" %f Free blocks in file system\n" \ " %f Free blocks in file system\n" \
USE_SELINUX( \
" %C Security context in SELinux\n" \
) \
" %i File System ID in hex\n" \ " %i File System ID in hex\n" \
" %l Maximum length of filenames\n" \ " %l Maximum length of filenames\n" \
" %n File name\n" \ " %n File name\n" \

View File

@ -3,6 +3,7 @@
* Mini copy_file implementation for busybox * Mini copy_file implementation for busybox
* *
* Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
* SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
* *
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* *
@ -62,6 +63,26 @@ int copy_file(const char *source, const char *dest, int flags)
dest_exists = 1; dest_exists = 1;
} }
#if ENABLE_SELINUX
if ((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) && is_selinux_enabled() > 0) {
security_context_t con;
if (lgetfilecon(source, &con) >= 0) {
if (setfscreatecon(con) < 0) {
bb_perror_msg("cannot set setfscreatecon %s", con);
freecon(con);
return -1;
}
} else {
if (errno == ENOTSUP || errno == ENODATA) {
setfscreatecon(NULL);
} else {
bb_perror_msg("cannot lgetfilecon %s", source);
return -1;
}
}
}
#endif
if (S_ISDIR(source_stat.st_mode)) { if (S_ISDIR(source_stat.st_mode)) {
DIR *dp; DIR *dp;
struct dirent *d; struct dirent *d;
@ -204,6 +225,25 @@ int copy_file(const char *source, const char *dest, int flags)
} }
} }
#if ENABLE_SELINUX
if (((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT)
|| (flags & FILEUTILS_SET_SECURITY_CONTEXT))
&& is_selinux_enabled() > 0) {
security_context_t con;
if (getfscreatecon(&con) == -1) {
bb_perror_msg("getfscreatecon");
return -1;
}
if (con) {
if(setfilecon(dest, con) == -1) {
bb_perror_msg("setfilecon:%s,%s", dest, con);
freecon(con);
return -1;
}
freecon(con);
}
}
#endif
if (bb_copyfd_eof(src_fd, dst_fd) == -1) if (bb_copyfd_eof(src_fd, dst_fd) == -1)
status = -1; status = -1;
if (close(dst_fd) < 0) { if (close(dst_fd) < 0) {

View File

@ -6,6 +6,20 @@
menu "Selinux Utilities" menu "Selinux Utilities"
depends on SELINUX depends on SELINUX
config CHCON
bool "chcon"
default n
depends on SELINUX
help
Enable support to change the security context of file.
config FEATURE_CHCON_LONG_OPTIONS
bool "Enable long options"
default y
depends on CHCON && GETOPT_LONG
help
Support long options for the chcon applet.
config GETENFORCE config GETENFORCE
bool "getenforce" bool "getenforce"
default n default n
@ -28,6 +42,20 @@ config MATCHPATHCON
Enable support to get default security context of the Enable support to get default security context of the
specified path from the file contexts configuration. specified path from the file contexts configuration.
config RUNCON
bool "runcon"
default n
depends on SELINUX
help
Enable support to run command in speficied security context.
config FEATURE_RUNCON_LONG_OPTIONS
bool "Enable long options"
default y
depends on RUNCON && GETOPT_LONG
help
Support long options for the runcon applet.
config SELINUXENABLED config SELINUXENABLED
bool "selinuxenabled" bool "selinuxenabled"
default n default n

View File

@ -6,8 +6,10 @@
# Licensed under the GPL v2, see the file LICENSE in this tarball. # Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:= lib-y:=
lib-$(CONFIG_CHCON) += chcon.o
lib-$(CONFIG_GETENFORCE) += getenforce.o lib-$(CONFIG_GETENFORCE) += getenforce.o
lib-$(CONFIG_GETSEBOOL) += getsebool.o lib-$(CONFIG_GETSEBOOL) += getsebool.o
lib-$(CONFIG_MATCHPATHCON) += matchpathcon.o lib-$(CONFIG_MATCHPATHCON) += matchpathcon.o
lib-$(CONFIG_RUNCON) += runcon.o
lib-$(CONFIG_SELINUXENABLED) += selinuxenabled.o lib-$(CONFIG_SELINUXENABLED) += selinuxenabled.o
lib-$(CONFIG_SETENFORCE) += setenforce.o lib-$(CONFIG_SETENFORCE) += setenforce.o