1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

[PATCH] PATCH selinux for udev

Daniel Walsh's working selinux patch
This commit is contained in:
harald@redhat.com 2004-10-05 23:39:05 -07:00 committed by Greg KH
parent ff213aecf6
commit 9825617b07
3 changed files with 149 additions and 0 deletions

View File

@ -25,6 +25,8 @@ USE_LOG = true
# Leave this set to `false' for production use. # Leave this set to `false' for production use.
DEBUG = false DEBUG = false
# Set this to compile with Security-Enhanced Linux support.
USE_SELINUX = false
ROOT = udev ROOT = udev
DAEMON = udevd DAEMON = udevd
@ -170,6 +172,11 @@ else
LDFLAGS = LDFLAGS =
endif endif
ifeq ($(strip $(USE_SELINUX)),true)
CFLAGS += -DUSE_SELINUX
LIB_OBJS += -lselinux
endif
CFLAGS += -I$(PWD)/libsysfs CFLAGS += -I$(PWD)/libsysfs
# config files automatically generated # config files automatically generated
@ -222,6 +229,7 @@ HEADERS = udev.h \
udevdb.h \ udevdb.h \
klibc_fixups.h \ klibc_fixups.h \
logging.h \ logging.h \
selinux.h \
list.h list.h
ifeq ($(strip $(USE_KLIBC)),true) ifeq ($(strip $(USE_KLIBC)),true)

131
selinux.h Normal file
View File

@ -0,0 +1,131 @@
#ifndef SELINUX_H
#define SELINUX_H
#ifndef USE_SELINUX
static inline void selinux_setfilecon(char *file, unsigned int mode) { }
static inline void selinux_setfscreatecon(char *file, unsigned int mode) {}
static inline void selinux_init(void) {}
static inline void selinux_restore(void) {}
#else
#include <selinux/selinux.h>
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
static int selinux_enabled=-1;
static security_context_t prev_scontext=NULL;
static inline int is_selinux_running(void) {
if ( selinux_enabled==-1 )
return selinux_enabled=is_selinux_enabled()>0;
return selinux_enabled;
}
static inline int selinux_get_media(char *path, int mode, char **media)
{
FILE *fp;
char buf[PATH_MAX];
char mediabuf[PATH_MAX];
*media=NULL;
if (!( mode && S_IFBLK )) {
return -1;
}
snprintf(buf,sizeof(buf), "/proc/ide/%s/media", basename(path));
fp=fopen(buf,"r");
if (fp) {
if (fgets(mediabuf,sizeof(mediabuf), fp)) {
int size=strlen(mediabuf);
while (size-- > 0) {
if (isspace(mediabuf[size])) {
mediabuf[size]='\0';
} else {
break;
}
}
*media=strdup(mediabuf);
info("selinux_get_media(%s)->%s \n", path, *media);
}
fclose(fp);
return 0;
} else {
return -1;
}
}
static inline void selinux_setfilecon(char *file, unsigned int mode) {
if (is_selinux_running()) {
security_context_t scontext=NULL;
char *media;
int ret=selinux_get_media(file, mode, &media);
if ( ret== 0) {
ret = matchmediacon(media, &scontext);
free(media);
}
if (ret==-1)
if (matchpathcon(file, mode, &scontext) < 0) {
dbg("matchpathcon(%s) failed\n", file);
return;
}
if (setfilecon(file, scontext) < 0)
dbg("setfiles %s failed with error '%s'",
file, strerror(errno));
freecon(scontext);
}
}
static inline void selinux_setfscreatecon(char *file, unsigned int mode) {
int retval = 0;
security_context_t scontext=NULL;
if (is_selinux_running()) {
char *media;
int ret=selinux_get_media(file, mode, &media);
if ( ret== 0) {
ret = matchmediacon(media, &scontext);
free(media);
}
if (ret==-1)
if (matchpathcon(file, mode, &scontext) < 0) {
dbg("matchpathcon(%s) failed\n", file);
return;
}
retval=setfscreatecon(scontext);
if (retval < 0)
dbg("setfiles %s failed with error '%s'",
file, strerror(errno));
freecon(scontext);
}
}
static inline void selinux_init(void) {
/* record the present security context, for file-creation
* restoration creation purposes.
*
*/
if (is_selinux_running())
{
if (getfscreatecon(&prev_scontext) < 0) {
dbg("getfscreatecon failed\n");
}
prev_scontext=NULL;
}
}
static inline void selinux_restore(void) {
if (is_selinux_running()) {
/* reset the file create context to its former glory */
if ( setfscreatecon(prev_scontext) < 0 )
dbg("setfscreatecon failed\n");
if (prev_scontext) {
freecon(prev_scontext);
prev_scontext=NULL;
}
}
}
#endif /* USE_SELINUX */
#endif /* SELINUX_H */

View File

@ -50,6 +50,8 @@
#define LOCAL_USER "$local" #define LOCAL_USER "$local"
#include "selinux.h"
/* /*
* Right now the major/minor of a device is stored in a file called * Right now the major/minor of a device is stored in a file called
* "dev" in sysfs. * "dev" in sysfs.
@ -92,6 +94,7 @@ static int create_path(char *file)
break; break;
*pos = 0x00; *pos = 0x00;
if (stat(p, &stats)) { if (stat(p, &stats)) {
selinux_setfscreatecon(p, S_IFDIR);
retval = mkdir(p, 0755); retval = mkdir(p, 0755);
if (retval != 0) { if (retval != 0) {
dbg("mkdir(%s) failed with error '%s'", dbg("mkdir(%s) failed with error '%s'",
@ -99,6 +102,8 @@ static int create_path(char *file)
return retval; return retval;
} }
dbg("created '%s'", p); dbg("created '%s'", p);
} else {
selinux_setfilecon(p, S_IFDIR);
} }
*pos = '/'; *pos = '/';
} }
@ -117,6 +122,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t
if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) &&
(stats.st_rdev == makedev(major, minor))) { (stats.st_rdev == makedev(major, minor))) {
dbg("preserve file '%s', cause it has correct dev_t", file); dbg("preserve file '%s', cause it has correct dev_t", file);
selinux_setfilecon(file,stats.st_mode);
goto perms; goto perms;
} }
@ -126,6 +132,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t
dbg("already present file '%s' unlinked", file); dbg("already present file '%s' unlinked", file);
create: create:
selinux_setfscreatecon(file, mode);
retval = mknod(file, mode, makedev(major, minor)); retval = mknod(file, mode, makedev(major, minor));
if (retval != 0) { if (retval != 0) {
dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
@ -304,6 +311,7 @@ static int create_node(struct udevice *dev, int fake)
dbg("symlink(%s, %s)", linktarget, filename); dbg("symlink(%s, %s)", linktarget, filename);
if (!fake) { if (!fake) {
selinux_setfscreatecon(filename, S_IFLNK);
unlink(filename); unlink(filename);
if (symlink(linktarget, filename) != 0) if (symlink(linktarget, filename) != 0)
dbg("symlink(%s, %s) failed with error '%s'", dbg("symlink(%s, %s) failed with error '%s'",
@ -438,6 +446,7 @@ int udev_add_device(const char *path, const char *subsystem, int fake)
dbg("name='%s'", dev.name); dbg("name='%s'", dev.name);
selinux_init();
switch (dev.type) { switch (dev.type) {
case 'b': case 'b':
case 'c': case 'c':
@ -475,6 +484,7 @@ int udev_add_device(const char *path, const char *subsystem, int fake)
} }
exit: exit:
selinux_restore();
sysfs_close_class_device(class_dev); sysfs_close_class_device(class_dev);
return retval; return retval;