Package: sysvinit Version: 2.86.ds1-1.se2 Severity: wishlist Tags: patch Hi,
Please consider turning on SELinux support for Sysvinit. Here is an updated patch, which works with the latest Se-Linux packages (has support for boolean setting, etc, using libsepol). This patch has been updated to the latest version of sysvinit, and should supplant bug reports 249515 and 242900. This patch also takes care not to break non-Linux builds, and only install SELinux code and dependencies for Linux machines, thus taking care of the objections raised in 242900. This has been tested on non-SELinux machines to ensure that there is no problem in the general case. manoj
diff -uBbwr sysvinit-2.86.ds1/debian/changelog sysvinit-2.86.ds1.selinux/debian/changelog --- sysvinit-2.86.ds1/debian/changelog 2005-03-03 18:12:11.000000000 -0600 +++ sysvinit-2.86.ds1.selinux/debian/changelog 2005-06-23 15:57:53.000000000 -0500 @@ -1,3 +1,18 @@ +sysvinit (2.86.ds1-1.se2) unstable; urgency=low + + * This ian NMU, built with SELinux support. This has been updated to the + latest SELinux libraries, and thus now buiuld depends on libsepol1-dev + as well. The patch has been fixed to not interfere with builds on + non-linux machines. + + -- Manoj Srivastava <[EMAIL PROTECTED]> Thu, 23 Jun 2005 15:57:53 -0500 + +sysvinit (2.86.ds1-1.se1) unstable; urgency=low + + * Build with SE Linux support. + + -- Russell Coker <[EMAIL PROTECTED]> Sat, 19 Feb 2005 16:13:00 +1100 + sysvinit (2.86.ds1-1) unstable; urgency=low * New upload with a clean .orig.tar.gz archive without the .o files. diff -uBbwr sysvinit-2.86.ds1/debian/control sysvinit-2.86.ds1.selinux/debian/control --- sysvinit-2.86.ds1/debian/control 2005-03-03 18:12:11.000000000 -0600 +++ sysvinit-2.86.ds1.selinux/debian/control 2005-06-23 15:54:58.000000000 -0500 @@ -3,7 +3,7 @@ Priority: required Maintainer: Miquel van Smoorenburg <[EMAIL PROTECTED]> Standards-Version: 3.5.2.0 -Build-Depends: bash +Build-Depends: bash, libselinux1-dev (>= 1.14-1) [!hurd-i386], libsepol1-dev [!hurd-i386] Package: sysvinit Essential: yes diff -uBbwr sysvinit-2.86.ds1/debian/rules sysvinit-2.86.ds1.selinux/debian/rules --- sysvinit-2.86.ds1/debian/rules 2005-03-03 18:12:11.000000000 -0600 +++ sysvinit-2.86.ds1.selinux/debian/rules 2005-06-23 15:48:42.000000000 -0500 @@ -12,7 +12,8 @@ DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_HOST_GNU_SYSTEM ?= $(shell dpkg-architecture -qDEB_HOST_GNU_SYSTEM) DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) - +export DEB_HOST_ARCH_OS := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS \ + 2>/dev/null|| true) LIBC6 = libc6 ifeq ($(DEB_HOST_ARCH), alpha) LIBC6 = libc6.1 @@ -28,7 +29,11 @@ build: # Builds the binary package. $(checkdir) +ifeq ($(DEB_HOST_ARCH_OS),linux) + (cd src; make DISTRO=Debian WITH_SELINUX="yes") +else (cd src; make DISTRO=Debian) +endif cc -Wall -s -o debian/readlink debian/readlink.c touch build diff -uBbwr sysvinit-2.86.ds1/src/Makefile sysvinit-2.86.ds1.selinux/src/Makefile --- sysvinit-2.86.ds1/src/Makefile 2004-06-09 07:47:45.000000000 -0500 +++ sysvinit-2.86.ds1.selinux/src/Makefile 2005-06-23 16:42:38.000000000 -0500 @@ -49,6 +49,18 @@ INSTALL = install -o $(BIN_OWNER) -g $(BIN_GROUP) MANDIR = /usr/share/man +ifeq ($(WITH_SELINUX),yes) + SELINUX_DEF=-DWITH_SELINUX + INIT_SELIBS=-lsepol -lselinux + SULOGIN_SELIBS=-lselinux +else + SELINUX_DEF= + INIT_SELIBS= + SULOGIN_SELIBS= +endif + + + # Additional libs for GNU libc. ifneq ($(wildcard /usr/lib/libcrypt.a),) LCRYPT = -lcrypt @@ -57,7 +69,7 @@ all: $(BIN) $(SBIN) $(USRBIN) init: init.o init_utmp.o - $(CC) $(LDFLAGS) $(STATIC) -o $@ init.o init_utmp.o + $(CC) $(LDFLAGS) $(STATIC) -o $@ init.o init_utmp.o $(INIT_SELIBS) halt: halt.o ifdown.o hddown.o utmp.o reboot.h $(CC) $(LDFLAGS) -o $@ halt.o ifdown.o hddown.o utmp.o @@ -78,7 +90,7 @@ $(CC) $(LDFLAGS) -o $@ runlevel.o sulogin: sulogin.o - $(CC) $(LDFLAGS) $(STATIC) -o $@ sulogin.o $(LCRYPT) + $(CC) $(LDFLAGS) $(STATIC) $(SELINUX_DEF) -o $@ $^ $(LCRYPT) $(SULOGIN_SELIBS) wall: dowall.o wall.o $(CC) $(LDFLAGS) -o $@ dowall.o wall.o @@ -89,8 +101,11 @@ bootlogd: bootlogd.o $(CC) $(LDFLAGS) -o $@ bootlogd.o -lutil +sulogin.o: sulogin.c + $(CC) -c $(CFLAGS) $(SELINUX_DEF) sulogin.c + init.o: init.c init.h set.h reboot.h initreq.h - $(CC) -c $(CFLAGS) init.c + $(CC) -c $(CFLAGS) $(SELINUX_DEF) init.c utmp.o: utmp.c init.h $(CC) -c $(CFLAGS) utmp.c diff -uBbwr sysvinit-2.86.ds1/src/init.c sysvinit-2.86.ds1.selinux/src/init.c --- sysvinit-2.86.ds1/src/init.c 2004-07-30 07:16:20.000000000 -0500 +++ sysvinit-2.86.ds1.selinux/src/init.c 2005-06-23 16:41:55.000000000 -0500 @@ -80,6 +81,157 @@ sigaction(sig, &sa, NULL); \ } while(0) + +#ifdef WITH_SELINUX +#include <sys/mman.h> +#include <selinux/selinux.h> +#include <sepol/sepol.h> +#include <sys/mount.h> + +/* Mount point for selinuxfs. */ +#define SELINUXMNT "/selinux/" +int enforcing = -1; /* SELinux enforcing mode */ + +static int load_policy(int *enforce) +{ + int fd=-1,ret=-1; + int rc=0, orig_enforce; + struct stat sb; + void *map; + char policy_file[PATH_MAX]; + int policy_version=0; + extern char *selinux_mnt; + FILE *cfg; + char buf[4096]; + int seconfig = -2; + + selinux_getenforcemode(&seconfig); + + mount("none", "/proc", "proc", 0, 0); + cfg = fopen("/proc/cmdline","r"); + if (cfg) { + char *tmp; + if (fgets(buf,4096,cfg) && (tmp = strstr(buf,"enforcing="))) { + if (tmp == buf || isspace(*(tmp-1))) { + enforcing=atoi(tmp+10); + } + } + fclose(cfg); + } +#define MNT_DETACH 2 + umount2("/proc",MNT_DETACH); + + if (enforcing >=0) + *enforce = enforcing; + else if (seconfig == 1) + *enforce = 1; + + if (mount("none", SELINUXMNT, "selinuxfs", 0, 0) < 0) { + if (errno == ENODEV) { + printf("SELinux not supported by kernel: %s\n",SELINUXMNT,strerror(errno)); + *enforce = 0; + } else { + printf("Failed to mount %s: %s\n",SELINUXMNT,strerror(errno)); + } + return ret; + } + + selinux_mnt = SELINUXMNT; /* set manually since we mounted it */ + + policy_version=security_policyvers(); + if (policy_version < 0) { + printf( "Can't get policy version: %s\n", strerror(errno)); + goto UMOUNT; + } + + orig_enforce = rc = security_getenforce(); + if (rc < 0) { + printf( "Can't get SELinux enforcement flag: %s\n", strerror(errno)); + goto UMOUNT; + } + if (enforcing >= 0) { + *enforce = enforcing; + } else if (seconfig == -1) { + *enforce = 0; + rc = security_disable(); + if (rc == 0) umount(SELINUXMNT); + if (rc < 0) { + rc = security_setenforce(0); + if (rc < 0) { + printf("Can't disable SELinux: %s\n", strerror(errno)); + goto UMOUNT; + } + } + ret = 0; + goto UMOUNT; + } else if (seconfig >= 0) { + *enforce = seconfig; + if (orig_enforce != *enforce) { + rc = security_setenforce(seconfig); + if (rc < 0) { + printf("Can't set SELinux enforcement flag: %s\n", strerror(errno)); + goto UMOUNT; + } + } + } + + snprintf(policy_file,sizeof(policy_file),"%s.%d",selinux_binary_policy_path(),policy_version); + fd = open(policy_file, O_RDONLY); + if (fd < 0) { + /* Check previous version to see if old policy is available + */ + snprintf(policy_file,sizeof(policy_file),"%s.%d",selinux_binary_policy_path(),policy_version-1); + fd = open(policy_file, O_RDONLY); + if (fd < 0) { + printf( "Can't open '%s.%d': %s\n", + selinux_binary_policy_path(),policy_version,strerror(errno)); + goto UMOUNT; + } + } + + if (fstat(fd, &sb) < 0) { + printf("Can't stat '%s': %s\n", + policy_file, strerror(errno)); + goto UMOUNT; + } + + map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) { + printf( "Can't map '%s': %s\n", + policy_file, strerror(errno)); + goto UMOUNT; + } + + + /* Set booleans based on a booleans configuration file. */ + ret = sepol_genbools(map, sb.st_size, selinux_booleans_path()); + if (ret < 0) { + if (errno == ENOENT || errno == EINVAL) { + /* No booleans file or stale booleans in the file; non-fatal. */ + printf("Warning! Error while setting booleans: %s\n" + , strerror(errno)); + } else { + printf("Error while setting booleans: %s\n", + strerror(errno)); + goto UMOUNT; + } + } + printf("Loading security policy\n"); + ret=security_load_policy(map, sb.st_size); + if (ret < 0) { + printf("security_load_policy failed\n"); + } + + UMOUNT: + /*umount(SELINUXMNT); */ + if ( fd >= 0) { + close(fd); + } + return(ret); +} +#endif + + /* Version information */ char *Version = "@(#) init " VERSION " " DATE " [EMAIL PROTECTED]"; char *bootmsg = "version " VERSION " %s"; @@ -2599,6 +2750,7 @@ char *p; int f; int isinit; + int enforce = 0; /* Get my own name */ if ((p = strrchr(argv[0], '/')) != NULL) @@ -2662,6 +2814,21 @@ maxproclen += strlen(argv[f]) + 1; } +#ifdef WITH_SELINUX + if (getenv("SELINUX_INIT") == NULL) { + putenv("SELINUX_INIT=YES"); + if (load_policy(&enforce) == 0 ) { + execv(myname, argv); + } else { + if (enforce > 0) { + /* SELinux in enforcing mode but load_policy failed */ + /* At this point, we probably can't open /dev/console, so log() won't work */ + fprintf(stderr,"Enforcing mode requested but no policy loaded. Halting now.\n"); + exit(1); + } + } + } +#endif /* Start booting. */ argv0 = argv[0]; argv[1] = NULL; diff -uBbwr sysvinit-2.86.ds1/src/killall5.c sysvinit-2.86.ds1.selinux/src/killall5.c --- sysvinit-2.86.ds1/src/killall5.c 2004-07-30 07:16:23.000000000 -0500 +++ sysvinit-2.86.ds1.selinux/src/killall5.c 2005-06-23 16:13:11.000000000 -0500 @@ -165,8 +165,11 @@ /* * Read the proc filesystem. + * since pidOf does not use process sid added a needSid flag to eliminate + * the need of this privs for SELinux + * */ -int readproc() +int readproc(int needSid) { DIR *dir; FILE *fp; @@ -259,7 +262,17 @@ free(p); continue; } - + if (needSid) { + p->sid = getsid(pid); + if (p->sid < 0) { + p->sid = 0; + nsyslog(LOG_ERR, "can't read sid for pid %d\n", pid); + free(p); + continue; + } + } else { + p->sid = 0; + } snprintf(path, sizeof(path), "/proc/%s/cmdline", d->d_name); if ((fp = fopen(path, "r")) != NULL) { @@ -519,7 +532,7 @@ argv += optind; /* Print out process-ID's one by one. */ - readproc(); + readproc(0); for(f = 0; f < argc; f++) { if ((q = pidof(argv[f])) != NULL) { spid = 0; @@ -600,7 +613,7 @@ sent_sigstop = 1; /* Read /proc filesystem */ - if (readproc() < 0) { + if (readproc(1) < 0) { kill(-1, SIGCONT); exit(1); } diff -uBbwr sysvinit-2.86.ds1/src/sulogin.c sysvinit-2.86.ds1.selinux/src/sulogin.c --- sysvinit-2.86.ds1/src/sulogin.c 2004-07-30 06:40:28.000000000 -0500 +++ sysvinit-2.86.ds1.selinux/src/sulogin.c 2005-06-23 15:16:17.000000000 -0500 @@ -28,6 +28,10 @@ # include <crypt.h> #endif +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#include <selinux/get_context_list.h> +#endif #define CHECK_DES 1 #define CHECK_MD5 1 @@ -335,6 +339,16 @@ signal(SIGINT, SIG_DFL); signal(SIGTSTP, SIG_DFL); signal(SIGQUIT, SIG_DFL); +#ifdef WITH_SELINUX + if (is_selinux_enabled > 0) { + security_context_t* contextlist=NULL; + if (get_ordered_context_list("root", 0, &contextlist) > 0) { + if (setexeccon(contextlist[0]) != 0) + fprintf(stderr, "setexeccon faile\n"); + freeconary(contextlist); + } + } +#endif execl(sushell, shell, NULL); perror(sushell);
-- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (500, 'stable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.11.2-skas3-v8-rc2 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C) Versions of packages sysvinit depends on: ii coreutils 5.2.1-2.gn1 The GNU core utilities ii initscripts 2.86.ds1-1.se2 Standard scripts needed for bootin ii libc6 2.3.2.ds1-22 GNU C Library: Shared libraries an ii libselinux1 1.22-1 SELinux shared libraries ii libsepol1 1.4-1 Security Enhanced Linux policy lib ii sysv-rc 2.86.ds1-1.se2 Standard boot mechanism using syml sysvinit recommends no packages. -- no debconf information -- Neckties strangle clear thinking. Lin Yutang Manoj Srivastava <[EMAIL PROTECTED]> <http://www.golden-gryphon.com/> 1024D/BF24424C print 4966 F272 D093 B493 410B 924B 21BA DABB BF24 424C