chiark / gitweb /
security: rework selinux, smack, ima, apparmor detection logic
[elogind.git] / src / shared / util.c
index fb42d663a6cfc4cad91a9b0582af35d31eab4627..31cea79f8b4674b6db33b96768bc9ebe760d5078 100644 (file)
@@ -2186,8 +2186,10 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
                                         return n > 0 ? n : -errno;
                                 }
 
-                                if (pollfd.revents != POLLIN)
-                                        return n > 0 ? n : -EIO;
+                                /* We knowingly ignore the revents value here,
+                                 * and expect that any error/EOF is reported
+                                 * via read()/write()
+                                 */
 
                                 continue;
                         }
@@ -2234,8 +2236,10 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
                                         return n > 0 ? n : -errno;
                                 }
 
-                                if (pollfd.revents != POLLOUT)
-                                        return n > 0 ? n : -EIO;
+                                /* We knowingly ignore the revents value here,
+                                 * and expect that any error/EOF is reported
+                                 * via read()/write()
+                                 */
 
                                 continue;
                         }
@@ -2420,6 +2424,25 @@ fallback:
         return random() * RAND_MAX + random();
 }
 
+unsigned random_u(void) {
+        _cleanup_close_ int fd;
+        unsigned u;
+        ssize_t r;
+
+        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                goto fallback;
+
+        r = loop_read(fd, &u, sizeof(u), true);
+        if (r != sizeof(u))
+                goto fallback;
+
+        return u;
+
+fallback:
+        return random() * RAND_MAX + random();
+}
+
 void rename_process(const char name[8]) {
         assert(name);
 
@@ -3504,7 +3527,7 @@ static char *tag_to_udev_node(const char *tagvalue, const char *by) {
         if (u == NULL)
                 return NULL;
 
-        enc_len = strlen(u) * 4;
+        enc_len = strlen(u) * 4 + 1;
         t = new(char, enc_len);
         if (t == NULL)
                 return NULL;
@@ -4033,8 +4056,9 @@ int vt_disallocate(const char *name) {
         return 0;
 }
 
-int copy_file(const char *from, const char *to) {
-        int r, fdf, fdt;
+int copy_file(const char *from, const char *to, int flags) {
+        _cleanup_close_ int fdf = -1;
+        int r, fdt;
 
         assert(from);
         assert(to);
@@ -4043,11 +4067,9 @@ int copy_file(const char *from, const char *to) {
         if (fdf < 0)
                 return -errno;
 
-        fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
-        if (fdt < 0) {
-                close_nointr_nofail(fdf);
+        fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
+        if (fdt < 0)
                 return -errno;
-        }
 
         for (;;) {
                 char buf[PIPE_BUF];
@@ -4057,7 +4079,6 @@ int copy_file(const char *from, const char *to) {
                 if (n < 0) {
                         r = -errno;
 
-                        close_nointr_nofail(fdf);
                         close_nointr(fdt);
                         unlink(to);
 
@@ -4072,15 +4093,13 @@ int copy_file(const char *from, const char *to) {
                 if (n != k) {
                         r = k < 0 ? k : (errno ? -errno : -EIO);
 
-                        close_nointr_nofail(fdf);
                         close_nointr(fdt);
-
                         unlink(to);
+
                         return r;
                 }
         }
 
-        close_nointr_nofail(fdf);
         r = close_nointr(fdt);
 
         if (r < 0) {