2929#include <sys/socket.h>
3030#include <sys/un.h>
3131#include <linux/netlink.h>
32+
33+ #ifdef HAVE_SELINUX
34+ #include <selinux/selinux.h>
35+ #include <selinux/label.h>
36+ #endif
37+
3238#include <private/android_filesystem_config.h>
3339#include <sys/time.h>
3440#include <asm/page.h>
4551#define FIRMWARE_DIR1 "/etc/firmware"
4652#define FIRMWARE_DIR2 "/vendor/firmware"
4753
54+ #ifdef HAVE_SELINUX
55+ static struct selabel_handle * sehandle ;
56+ #endif
57+
4858static int device_fd = -1 ;
4959
5060struct uevent {
@@ -180,8 +190,17 @@ static void make_device(const char *path,
180190 unsigned gid ;
181191 mode_t mode ;
182192 dev_t dev ;
193+ #ifdef HAVE_SELINUX
194+ char * secontext = NULL ;
195+ #endif
183196
184197 mode = get_device_perm (path , & uid , & gid ) | (block ? S_IFBLK : S_IFCHR );
198+ #ifdef HAVE_SELINUX
199+ if (sehandle ) {
200+ selabel_lookup (sehandle , & secontext , path , mode );
201+ setfscreatecon (secontext );
202+ }
203+ #endif
185204 dev = makedev (major , minor );
186205 /* Temporarily change egid to avoid race condition setting the gid of the
187206 * device node. Unforunately changing the euid would prevent creation of
@@ -192,8 +211,40 @@ static void make_device(const char *path,
192211 mknod (path , mode , dev );
193212 chown (path , uid , -1 );
194213 setegid (AID_ROOT );
214+ #ifdef HAVE_SELINUX
215+ if (secontext ) {
216+ freecon (secontext );
217+ setfscreatecon (NULL );
218+ }
219+ #endif
220+ }
221+
222+
223+ static int make_dir (const char * path , mode_t mode )
224+ {
225+ int rc ;
226+
227+ #ifdef HAVE_SELINUX
228+ char * secontext = NULL ;
229+
230+ if (sehandle ) {
231+ selabel_lookup (sehandle , & secontext , path , mode );
232+ setfscreatecon (secontext );
233+ }
234+ #endif
235+
236+ rc = mkdir (path , mode );
237+
238+ #ifdef HAVE_SELINUX
239+ if (secontext ) {
240+ freecon (secontext );
241+ setfscreatecon (NULL );
242+ }
243+ #endif
244+ return rc ;
195245}
196246
247+
197248static void add_platform_device (const char * name )
198249{
199250 int name_len = strlen (name );
@@ -506,7 +557,7 @@ static void handle_block_device_event(struct uevent *uevent)
506557 return ;
507558
508559 snprintf (devpath , sizeof (devpath ), "%s%s" , base , name );
509- mkdir (base , 0755 );
560+ make_dir (base , 0755 );
510561
511562 if (!strncmp (uevent -> path , "/devices/platform/" , 18 ))
512563 links = parse_platform_block_device (uevent );
@@ -535,40 +586,40 @@ static void handle_generic_device_event(struct uevent *uevent)
535586 int bus_id = uevent -> minor / 128 + 1 ;
536587 int device_id = uevent -> minor % 128 + 1 ;
537588 /* build directories */
538- mkdir ("/dev/bus" , 0755 );
539- mkdir ("/dev/bus/usb" , 0755 );
589+ make_dir ("/dev/bus" , 0755 );
590+ make_dir ("/dev/bus/usb" , 0755 );
540591 snprintf (devpath , sizeof (devpath ), "/dev/bus/usb/%03d" , bus_id );
541- mkdir (devpath , 0755 );
592+ make_dir (devpath , 0755 );
542593 snprintf (devpath , sizeof (devpath ), "/dev/bus/usb/%03d/%03d" , bus_id , device_id );
543594 } else {
544595 /* ignore other USB events */
545596 return ;
546597 }
547598 } else if (!strncmp (uevent -> subsystem , "graphics" , 8 )) {
548599 base = "/dev/graphics/" ;
549- mkdir (base , 0755 );
600+ make_dir (base , 0755 );
550601 } else if (!strncmp (uevent -> subsystem , "oncrpc" , 6 )) {
551602 base = "/dev/oncrpc/" ;
552- mkdir (base , 0755 );
603+ make_dir (base , 0755 );
553604 } else if (!strncmp (uevent -> subsystem , "adsp" , 4 )) {
554605 base = "/dev/adsp/" ;
555- mkdir (base , 0755 );
606+ make_dir (base , 0755 );
556607 } else if (!strncmp (uevent -> subsystem , "msm_camera" , 10 )) {
557608 base = "/dev/msm_camera/" ;
558- mkdir (base , 0755 );
609+ make_dir (base , 0755 );
559610 } else if (!strncmp (uevent -> subsystem , "input" , 5 )) {
560611 base = "/dev/input/" ;
561- mkdir (base , 0755 );
612+ make_dir (base , 0755 );
562613 } else if (!strncmp (uevent -> subsystem , "mtd" , 3 )) {
563614 base = "/dev/mtd/" ;
564- mkdir (base , 0755 );
615+ make_dir (base , 0755 );
565616 } else if (!strncmp (uevent -> subsystem , "sound" , 5 )) {
566617 base = "/dev/snd/" ;
567- mkdir (base , 0755 );
618+ make_dir (base , 0755 );
568619 } else if (!strncmp (uevent -> subsystem , "misc" , 4 ) &&
569620 !strncmp (name , "log_" , 4 )) {
570621 base = "/dev/log/" ;
571- mkdir (base , 0755 );
622+ make_dir (base , 0755 );
572623 name += 4 ;
573624 } else
574625 base = "/dev/" ;
@@ -819,7 +870,14 @@ void device_init(void)
819870 suseconds_t t0 , t1 ;
820871 struct stat info ;
821872 int fd ;
873+ #ifdef HAVE_SELINUX
874+ struct selinux_opt seopts [] = {
875+ { SELABEL_OPT_PATH , "/file_contexts" }
876+ };
822877
878+ if (is_selinux_enabled () > 0 )
879+ sehandle = selabel_open (SELABEL_CTX_FILE , seopts , 1 );
880+ #endif
823881 /* is 64K enough? udev uses 16MB! */
824882 device_fd = uevent_open_socket (64 * 1024 , true);
825883 if (device_fd < 0 )
0 commit comments