Exemplo n.º 1
0
static void
process_extended_fstatvfs(u_int32_t id)
{
	int handle, fd;
	struct statvfs st;

	handle = get_handle();
	debug("request %u: fstatvfs \"%s\" (handle %u)",
	    id, handle_to_name(handle), handle);
	if ((fd = handle_to_fd(handle)) < 0) {
		send_status(id, SSH2_FX_FAILURE);
		return;
	}
	if (fstatvfs(fd, &st) != 0)
		send_status(id, errno_to_portable(errno));
	else
		send_statvfs(id, &st);
}
Exemplo n.º 2
0
long
fpathconf(int fd, int name)
{
	struct statvfs fs;
	struct stat st;
	int ret;
	if (fd < 0) {
		__set_errno(EBADF);
		return -1;
	}
	ret = fstat(fd, &st);
	if (ret < 0)
		return ret;
	ret = fstatvfs(fd, &fs);
	if (ret < 0)
		return ret;
	return __pathconf_common(&fs, &st, name);
}
Exemplo n.º 3
0
static void
process_extended_fstatvfs(u_int32_t id)
{
	int r, handle, fd;
	struct statvfs st;

	if ((r = get_handle(iqueue, &handle)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	debug("request %u: fstatvfs \"%s\" (handle %u)",
	    id, handle_to_name(handle), handle);
	if ((fd = handle_to_fd(handle)) < 0) {
		send_status(id, SSH2_FX_FAILURE);
		return;
	}
	if (fstatvfs(fd, &st) != 0)
		send_status(id, errno_to_portable(errno));
	else
		send_statvfs(id, &st);
}
Exemplo n.º 4
0
/**
 * Funkce inicializující strukturu statvfs
 *
 *  struct statvfs {
 *    unsigned long  f_bsize;    file system block size
 *    unsigned long  f_frsize;   fragment size
 *    fsblkcnt_t     f_blocks;   size of fs in f_frsize units
 *    fsblkcnt_t     f_bfree;    # free blocks
 *    fsblkcnt_t     f_bavail;   # free blocks for unprivileged users
 *    fsfilcnt_t     f_files;    # inodes
 *    fsfilcnt_t     f_ffree;    # free inodes
 *    fsfilcnt_t     f_favail;   # free inodes for unprivileged users
 *    unsigned long  f_fsid;     file system ID
 *    unsigned long  f_flag;     mount flags
 *    unsigned long  f_namemax;  maximum filename length
 *  };
 *
 * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
 */
void FileSystem::initStatvfs() {
  memset(&archive_statvfs, 0, sizeof(struct statvfs));

  struct statvfs buf;

  if (fstatvfs(archive_file, &buf) != 0) return;

  // Volné místo zjistíme podle "underlying" filesystému
  archive_statvfs.f_bavail = archive_statvfs.f_bfree = buf.f_frsize * buf.f_bavail;

  archive_statvfs.f_bsize = 1;

  // Velikost vfs v blocích
  archive_statvfs.f_blocks = buf.f_bavail;

  archive_statvfs.f_files = file_map.size() - 1; // - root node
  archive_statvfs.f_namemax = 255;

  return;
}
Exemplo n.º 5
0
/* Return information about the filesystem on which FD resides.  */
int
__fstatvfs64 (int fd, struct statvfs64 *buf)
{
  struct statfs64 fsbuf;
  int res = __fstatfs64 (fd, &fsbuf);

#ifndef __ASSUME_STATFS64
  if (res < 0 && errno == ENOSYS)
    {
      struct statvfs buf32;

      res = fstatvfs (fd, &buf32);
      if (res == 0)
	{
	  buf->f_bsize = buf32.f_bsize;
	  buf->f_frsize = buf32.f_frsize;
	  buf->f_blocks = buf32.f_blocks;
	  buf->f_bfree = buf32.f_bfree;
	  buf->f_bavail = buf32.f_bavail;
	  buf->f_files = buf32.f_files;
	  buf->f_ffree = buf32.f_ffree;
	  buf->f_favail = buf32.f_favail;
	  buf->f_fsid = buf32.f_fsid;
	  buf->f_flag = buf32.f_flag;
	  buf->f_namemax = buf32.f_namemax;
	  memcpy (buf->__f_spare, buf32.__f_spare, sizeof (buf32.__f_spare));
	}
    }
#endif

  if (res == 0)
    {
      /* Convert the result.  */
      struct stat64 st;
      __internal_statvfs64 (NULL, buf, &fsbuf,
			    fstat64 (fd, &st) == -1 ? NULL : &st);
    }

  return res;
}
RTR3DECL(int) RTFileQueryFsSizes(RTFILE hFile, PRTFOFF pcbTotal, RTFOFF *pcbFree,
                                 uint32_t *pcbBlock, uint32_t *pcbSector)
{
    struct statvfs StatVFS;
    RT_ZERO(StatVFS);
    if (fstatvfs(RTFileToNative(hFile), &StatVFS))
        return RTErrConvertFromErrno(errno);

    /*
     * Calc the returned values.
     */
    if (pcbTotal)
        *pcbTotal = (RTFOFF)StatVFS.f_blocks * StatVFS.f_frsize;
    if (pcbFree)
        *pcbFree = (RTFOFF)StatVFS.f_bavail * StatVFS.f_frsize;
    if (pcbBlock)
        *pcbBlock = StatVFS.f_frsize;
    /* no idea how to get the sector... */
    if (pcbSector)
        *pcbSector = 512;

    return VINF_SUCCESS;
}
Exemplo n.º 7
0
/* Return information about the filesystem on which FD resides.  */
int
__fstatvfs64 (int fd, struct statvfs64 *buf)
{
  struct statvfs buf32;

  if (fstatvfs (fd, &buf32) < 0)
    return -1;

  buf->f_bsize = buf32.f_bsize;
  buf->f_frsize = buf32.f_frsize;
  buf->f_blocks = buf32.f_blocks;
  buf->f_bfree = buf32.f_bfree;
  buf->f_bavail = buf32.f_bavail;
  buf->f_files = buf32.f_files;
  buf->f_ffree = buf32.f_ffree;
  buf->f_favail = buf32.f_favail;
  buf->f_fsid = buf32.f_fsid;
  buf->f_flag = buf32.f_flag;
  buf->f_namemax = buf32.f_namemax;
  memcpy (buf->__f_spare, buf32.__f_spare, sizeof (buf32.__f_spare));

  return 0;
}
Exemplo n.º 8
0
static int
do_test (void)
{
  char *buf;
  int fd;
  FILE *fp;
  int ch;
  struct stat st1;
  struct stat st2;

  buf = (char *) malloc (strlen (test_dir) + sizeof "/tst-atime.XXXXXX");
  if (buf == NULL)
    {
      printf ("cannot allocate memory: %m\n");
      return 1;
    }
  stpcpy (stpcpy (buf, test_dir), "/tst-atime.XXXXXX");

  fd = mkstemp (buf);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

#ifdef ST_NOATIME
  /* Make sure the filesystem doesn't have the noatime option set.  If
     statvfs is not available just continue.  */
  struct statvfs sv;
  int e = fstatvfs (fd, &sv);
  if (e != ENOSYS)
    {
      if (e != 0)
	{
	  printf ("cannot statvfs '%s': %m\n", buf);
	  return 1;
	}

      if ((sv.f_flag & ST_NOATIME) != 0)
	{
	  puts ("Bah!  The filesystem is mounted with noatime");
	  return 0;
	}
    }
#endif

  /* Make sure it gets removed.  */
  add_temp_file (buf);

  if (write (fd, "some string\n", 12) != 12)
    {
      printf ("cannot write temporary file: %m\n");
      return 1;
    }

  if (lseek (fd, 0, SEEK_SET) == (off_t) -1)
    {
      printf ("cannot reposition temporary file: %m\n");
      return 1;
    }

  fp = fdopen (fd, "r");
  if (fp == NULL)
    {
      printf ("cannot create stream: %m\n");
      return 1;
    }

  if (fstat (fd, &st1) == -1)
    {
      printf ("first stat failed: %m\n");
      return 1;
    }

  sleep (2);

  ch = fgetc (fp);
  if (ch != 's')
    {
      printf ("did not read correct character: got '%c', expected 's'\n", ch);
      return 1;
    }

  if (fstat (fd, &st2) == -1)
    {
      printf ("second stat failed: %m\n");
      return 1;
    }

  if (st1.st_atime > st2.st_atime)
    {
      puts ("second atime smaller");
      return 1;
    }
  else if (st1.st_atime == st2.st_atime)
    {
      puts ("atime has not changed");
      return 1;
    }

  fclose (fp);

  return 0;
}
Exemplo n.º 9
0
/* XXX This function really should be cancellable (for the benefit of
 * virt-sparsify).  However currently the library can only handle
 * cancellation for FileIn/FileOut operations.
 */
int
do_zero_free_space (const char *dir)
{
  size_t len = strlen (dir);
  char filename[sysroot_len+len+14]; /* sysroot + dir + "/" + 8.3 + "\0" */
  int fd;
  unsigned skip = 0;
  struct statvfs statbuf;
  fsblkcnt_t bfree_initial;

  /* Choose a randomly named 8.3 file.  Because of the random name,
   * this won't conflict with existing files, and it should be
   * compatible with any filesystem type inc. FAT.
   */
  snprintf (filename, sysroot_len+len+14, "%s%s/XXXXXXXX.XXX", sysroot, dir);
  if (random_name (filename) == -1) {
    reply_with_perror ("random_name");
    return -1;
  }

  if (verbose)
    printf ("random filename: %s\n", filename);

  /* Open file and fill with zeroes until we run out of space. */
  fd = open (filename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600);
  if (fd == -1) {
    reply_with_perror ("open: %s", filename);
    return -1;
  }

  /* To estimate progress in this operation, we're going to track
   * free blocks in this filesystem down to zero.
   */
  if (fstatvfs (fd, &statbuf) == -1) {
    reply_with_perror ("fstatvfs");
    close (fd);
    return -1;
  }
  bfree_initial = statbuf.f_bfree;

  for (;;) {
    if (write (fd, zero_buf, sizeof zero_buf) == -1) {
      if (errno == ENOSPC)      /* expected error */
        break;
      reply_with_perror ("write: %s", filename);
      close (fd);
      unlink (filename);
      return -1;
    }

    skip++;
    if ((skip & 256) == 0 && fstatvfs (fd, &statbuf) == 0)
      notify_progress (bfree_initial - statbuf.f_bfree, bfree_initial);
  }

  /* Make sure the file is completely written to disk. */
  close (fd); /* expect this to give an error, don't check it */

  sync_disks ();

  notify_progress (bfree_initial, bfree_initial);

  /* Remove the file. */
  if (unlink (filename) == -1) {
    reply_with_perror ("unlink: %s", filename);
    return -1;
  }

  return 0;
}
Exemplo n.º 10
0
static int
getentropy_fallback(void *buf, size_t len)
{
	uint8_t results[SHA512_DIGEST_LENGTH];
	int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat;
	static int cnt;
	struct timespec ts;
	struct timeval tv;
	perfstat_cpu_total_t cpustats;
#ifdef _AIX61
	perfstat_cpu_total_wpar_t cpustats_wpar;
#endif
	perfstat_partition_total_t lparstats;
	perfstat_disk_total_t diskinfo;
	perfstat_netinterface_total_t netinfo;
	struct rusage ru;
	sigset_t sigset;
	struct stat st;
	SHA512_CTX ctx;
	static pid_t lastpid;
	pid_t pid;
	size_t i, ii, m;
	char *p;

	pid = getpid();
	if (lastpid == pid) {
		faster = 1;
		repeat = 2;
	} else {
		faster = 0;
		lastpid = pid;
		repeat = REPEAT;
	}
	for (i = 0; i < len; ) {
		int j;
		SHA512_Init(&ctx);
		for (j = 0; j < repeat; j++) {
			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HX(perfstat_cpu_total(NULL, &cpustats,
			    sizeof(cpustats), 1) == -1, cpustats);

#ifdef _AIX61
			HX(perfstat_cpu_total_wpar(NULL, &cpustats_wpar,
			    sizeof(cpustats_wpar), 1) == -1, cpustats_wpar);
#endif

			HX(perfstat_partition_total(NULL, &lparstats,
			    sizeof(lparstats), 1) == -1, lparstats);

			HX(perfstat_disk_total(NULL, &diskinfo,
			    sizeof(diskinfo), 1) == -1, diskinfo);

			HX(perfstat_netinterface_total(NULL, &netinfo,
			    sizeof(netinfo), 1) == -1, netinfo);

			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
				HX(clock_gettime(cl[ii], &ts) == -1, ts);

			HX((pid = getpid()) == -1, pid);
			HX((pid = getsid(pid)) == -1, pid);
			HX((pid = getppid()) == -1, pid);
			HX((pid = getpgid(0)) == -1, pid);
			HX((e = getpriority(0, 0)) == -1, e);

			if (!faster) {
				ts.tv_sec = 0;
				ts.tv_nsec = 1;
				(void) nanosleep(&ts, NULL);
			}

			HX(sigpending(&sigset) == -1, sigset);
			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
			    sigset);

			HF(getentropy);	/* an addr in this library */
			HF(printf);		/* an addr in libc */
			p = (char *)&p;
			HD(p);		/* an addr on stack */
			p = (char *)&errno;
			HD(p);		/* the addr of errno */

			if (i == 0) {
				struct sockaddr_storage ss;
				struct statvfs stvfs;
				struct termios tios;
				socklen_t ssl;
				off_t off;

				/*
				 * Prime-sized mappings encourage fragmentation;
				 * thus exposing some address entropy.
				 */
				struct mm {
					size_t	npg;
					void	*p;
				} mm[] =	 {
					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
				};

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					HX(mm[m].p = mmap(NULL,
					    mm[m].npg * pgs,
					    PROT_READ|PROT_WRITE,
					    MAP_PRIVATE|MAP_ANON, -1,
					    (off_t)0), mm[m].p);
					if (mm[m].p != MAP_FAILED) {
						size_t mo;

						/* Touch some memory... */
						p = mm[m].p;
						mo = cnt %
						    (mm[m].npg * pgs - 1);
						p[mo] = 1;
						cnt += (int)((long)(mm[m].p)
						    / pgs);
					}

					/* Check cnts and times... */
					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
					    ii++) {
						HX((e = clock_gettime(cl[ii],
						    &ts)) == -1, ts);
						if (e != -1)
							cnt += (int)ts.tv_nsec;
					}

					HX((e = getrusage(RUSAGE_SELF,
					    &ru)) == -1, ru);
					if (e != -1) {
						cnt += (int)ru.ru_utime.tv_sec;
						cnt += (int)ru.ru_utime.tv_usec;
					}
				}

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					if (mm[m].p != MAP_FAILED)
						munmap(mm[m].p, mm[m].npg * pgs);
					mm[m].p = MAP_FAILED;
				}

				HX(stat(".", &st) == -1, st);
				HX(statvfs(".", &stvfs) == -1, stvfs);

				HX(stat("/", &st) == -1, st);
				HX(statvfs("/", &stvfs) == -1, stvfs);

				HX((e = fstat(0, &st)) == -1, st);
				if (e == -1) {
					if (S_ISREG(st.st_mode) ||
					    S_ISFIFO(st.st_mode) ||
					    S_ISSOCK(st.st_mode)) {
						HX(fstatvfs(0, &stvfs) == -1,
						    stvfs);
						HX((off = lseek(0, (off_t)0,
						    SEEK_CUR)) < 0, off);
					}
					if (S_ISCHR(st.st_mode)) {
						HX(tcgetattr(0, &tios) == -1,
						    tios);
					} else if (S_ISSOCK(st.st_mode)) {
						memset(&ss, 0, sizeof ss);
						ssl = sizeof(ss);
						HX(getpeername(0,
						    (void *)&ss, &ssl) == -1,
						    ss);
					}
				}

				HX((e = getrusage(RUSAGE_CHILDREN,
				    &ru)) == -1, ru);
				if (e != -1) {
					cnt += (int)ru.ru_utime.tv_sec;
					cnt += (int)ru.ru_utime.tv_usec;
				}
			} else {
				/* Subsequent hashes absorb previous result */
				HD(results);
			}

			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HD(cnt);
		}
		SHA512_Final(results, &ctx);
		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
		i += min(sizeof(results), len - i);
	}
	explicit_bzero(&ctx, sizeof ctx);
	explicit_bzero(results, sizeof results);
	if (gotdata(buf, len) == 0) {
		errno = save_errno;
		return 0;		/* satisfied */
	}
	errno = EIO;
	return -1;
}
Exemplo n.º 11
0
void server_process_native_file(
                Server *s,
                int fd,
                const struct ucred *ucred,
                const struct timeval *tv,
                const char *label, size_t label_len) {

        struct stat st;
        bool sealed;
        int r;

        /* Data is in the passed fd, since it didn't fit in a
         * datagram. */

        assert(s);
        assert(fd >= 0);

        /* If it's a memfd, check if it is sealed. If so, we can just
         * use map it and use it, and do not need to copy the data
         * out. */
        sealed = memfd_get_sealed(fd) > 0;

        if (!sealed && (!ucred || ucred->uid != 0)) {
                _cleanup_free_ char *sl = NULL, *k = NULL;
                const char *e;

                /* If this is not a sealed memfd, and the peer is unknown or
                 * unprivileged, then verify the path. */

                if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
                        log_oom();
                        return;
                }

                r = readlink_malloc(sl, &k);
                if (r < 0) {
                        log_error_errno(r, "readlink(%s) failed: %m", sl);
                        return;
                }

                e = path_startswith(k, "/dev/shm/");
                if (!e)
                        e = path_startswith(k, "/tmp/");
                if (!e)
                        e = path_startswith(k, "/var/tmp/");
                if (!e) {
                        log_error("Received file outside of allowed directories. Refusing.");
                        return;
                }

                if (!filename_is_valid(e)) {
                        log_error("Received file in subdirectory of allowed directories. Refusing.");
                        return;
                }
        }

        if (fstat(fd, &st) < 0) {
                log_error_errno(errno, "Failed to stat passed file, ignoring: %m");
                return;
        }

        if (!S_ISREG(st.st_mode)) {
                log_error("File passed is not regular. Ignoring.");
                return;
        }

        if (st.st_size <= 0)
                return;

        if (st.st_size > ENTRY_SIZE_MAX) {
                log_error("File passed too large. Ignoring.");
                return;
        }

        if (sealed) {
                void *p;
                size_t ps;

                /* The file is sealed, we can just map it and use it. */

                ps = PAGE_ALIGN(st.st_size);
                p = mmap(NULL, ps, PROT_READ, MAP_PRIVATE, fd, 0);
                if (p == MAP_FAILED) {
                        log_error_errno(errno, "Failed to map memfd, ignoring: %m");
                        return;
                }

                server_process_native_message(s, p, st.st_size, ucred, tv, label, label_len);
                assert_se(munmap(p, ps) >= 0);
        } else {
                _cleanup_free_ void *p = NULL;
                struct statvfs vfs;
                ssize_t n;

                if (fstatvfs(fd, &vfs) < 0) {
                        log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m");
                        return;
                }

                /* Refuse operating on file systems that have
                 * mandatory locking enabled, see:
                 *
                 * https://github.com/systemd/systemd/issues/1822
                 */
                if (vfs.f_flag & ST_MANDLOCK) {
                        log_error("Received file descriptor from file system with mandatory locking enable, refusing.");
                        return;
                }

                /* Make the fd non-blocking. On regular files this has
                 * the effect of bypassing mandatory locking. Of
                 * course, this should normally not be necessary given
                 * the check above, but let's better be safe than
                 * sorry, after all NFS is pretty confusing regarding
                 * file system flags, and we better don't trust it,
                 * and so is SMB. */
                r = fd_nonblock(fd, true);
                if (r < 0) {
                        log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m");
                        return;
                }

                /* The file is not sealed, we can't map the file here, since
                 * clients might then truncate it and trigger a SIGBUS for
                 * us. So let's stupidly read it */

                p = malloc(st.st_size);
                if (!p) {
                        log_oom();
                        return;
                }

                n = pread(fd, p, st.st_size, 0);
                if (n < 0)
                        log_error_errno(errno, "Failed to read file, ignoring: %m");
                else if (n > 0)
                        server_process_native_message(s, p, n, ucred, tv, label, label_len);
        }
}
Exemplo n.º 12
0
static int
getentropy_fallback(void *buf, size_t len)
{
	uint8_t results[SHA512_DIGEST_LENGTH];
	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
	static int cnt;
	struct timespec ts;
	struct timeval tv;
	struct rusage ru;
	sigset_t sigset;
	struct stat st;
	SHA512_CTX ctx;
	static pid_t lastpid;
	pid_t pid;
	size_t i, ii, m;
	char *p;
	struct tcpstat tcpstat;
	struct udpstat udpstat;
	struct ipstat ipstat;
	u_int64_t mach_time;
	unsigned int idata;
	void *addr;

	pid = getpid();
	if (lastpid == pid) {
		faster = 1;
		repeat = 2;
	} else {
		faster = 0;
		lastpid = pid;
		repeat = REPEAT;
	}
	for (i = 0; i < len; ) {
		int j;
		SHA512_Init(&ctx);
		for (j = 0; j < repeat; j++) {
			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			mach_time = mach_absolute_time();
			HD(mach_time);

			ii = sizeof(addr);
			HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
			    &addr, &ii, NULL, 0) == -1, addr);

			ii = sizeof(idata);
			HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
			    &idata, &ii, NULL, 0) == -1, idata);

			ii = sizeof(tcpstat);
			HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
			    &tcpstat, &ii, NULL, 0) == -1, tcpstat);

			ii = sizeof(udpstat);
			HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
			    &udpstat, &ii, NULL, 0) == -1, udpstat);

			ii = sizeof(ipstat);
			HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
			    &ipstat, &ii, NULL, 0) == -1, ipstat);

			HX((pid = getpid()) == -1, pid);
			HX((pid = getsid(pid)) == -1, pid);
			HX((pid = getppid()) == -1, pid);
			HX((pid = getpgid(0)) == -1, pid);
			HX((e = getpriority(0, 0)) == -1, e);

			if (!faster) {
				ts.tv_sec = 0;
				ts.tv_nsec = 1;
				(void) nanosleep(&ts, NULL);
			}

			HX(sigpending(&sigset) == -1, sigset);
			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
			    sigset);

			HF(getentropy);	/* an addr in this library */
			HF(printf);		/* an addr in libc */
			p = (char *)&p;
			HD(p);		/* an addr on stack */
			p = (char *)&errno;
			HD(p);		/* the addr of errno */

			if (i == 0) {
				struct sockaddr_storage ss;
				struct statvfs stvfs;
				struct termios tios;
				struct statfs stfs;
				socklen_t ssl;
				off_t off;

				/*
				 * Prime-sized mappings encourage fragmentation;
				 * thus exposing some address entropy.
				 */
				struct mm {
					size_t	npg;
					void	*p;
				} mm[] =	 {
					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
				};

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					HX(mm[m].p = mmap(NULL,
					    mm[m].npg * pgs,
					    PROT_READ|PROT_WRITE,
					    MAP_PRIVATE|MAP_ANON, -1,
					    (off_t)0), mm[m].p);
					if (mm[m].p != MAP_FAILED) {
						size_t mo;

						/* Touch some memory... */
						p = mm[m].p;
						mo = cnt %
						    (mm[m].npg * pgs - 1);
						p[mo] = 1;
						cnt += (int)((long)(mm[m].p)
						    / pgs);
					}

					/* Check cnts and times... */
					mach_time = mach_absolute_time();
					HD(mach_time);
					cnt += (int)mach_time;

					HX((e = getrusage(RUSAGE_SELF,
					    &ru)) == -1, ru);
					if (e != -1) {
						cnt += (int)ru.ru_utime.tv_sec;
						cnt += (int)ru.ru_utime.tv_usec;
					}
				}

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					if (mm[m].p != MAP_FAILED)
						munmap(mm[m].p, mm[m].npg * pgs);
					mm[m].p = MAP_FAILED;
				}

				HX(stat(".", &st) == -1, st);
				HX(statvfs(".", &stvfs) == -1, stvfs);
				HX(statfs(".", &stfs) == -1, stfs);

				HX(stat("/", &st) == -1, st);
				HX(statvfs("/", &stvfs) == -1, stvfs);
				HX(statfs("/", &stfs) == -1, stfs);

				HX((e = fstat(0, &st)) == -1, st);
				if (e == -1) {
					if (S_ISREG(st.st_mode) ||
					    S_ISFIFO(st.st_mode) ||
					    S_ISSOCK(st.st_mode)) {
						HX(fstatvfs(0, &stvfs) == -1,
						    stvfs);
						HX(fstatfs(0, &stfs) == -1,
						    stfs);
						HX((off = lseek(0, (off_t)0,
						    SEEK_CUR)) < 0, off);
					}
					if (S_ISCHR(st.st_mode)) {
						HX(tcgetattr(0, &tios) == -1,
						    tios);
					} else if (S_ISSOCK(st.st_mode)) {
						memset(&ss, 0, sizeof ss);
						ssl = sizeof(ss);
						HX(getpeername(0,
						    (void *)&ss, &ssl) == -1,
						    ss);
					}
				}

				HX((e = getrusage(RUSAGE_CHILDREN,
				    &ru)) == -1, ru);
				if (e != -1) {
					cnt += (int)ru.ru_utime.tv_sec;
					cnt += (int)ru.ru_utime.tv_usec;
				}
			} else {
				/* Subsequent hashes absorb previous result */
				HD(results);
			}

			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HD(cnt);
		}

		SHA512_Final(results, &ctx);
		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
		i += min(sizeof(results), len - i);
	}
	explicit_bzero(&ctx, sizeof ctx);
	explicit_bzero(results, sizeof results);
	if (gotdata(buf, len) == 0) {
		errno = save_errno;
		return (0);		/* satisfied */
	}
	errno = EIO;
	return (-1);
}
Exemplo n.º 13
0
static int
getentropy_fallback(void *buf, size_t len)
{
	uint8_t results[SHA512_DIGEST_LENGTH];
	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
	static int cnt;
	struct timespec ts;
	struct timeval tv;
	struct rusage ru;
	sigset_t sigset;
	struct stat st;
	SHA512_CTX ctx;
	static pid_t lastpid;
	pid_t pid;
	size_t i, ii, m;
	char *p;

	pid = getpid();
	if (lastpid == pid) {
		faster = 1;
		repeat = 2;
	} else {
		faster = 0;
		lastpid = pid;
		repeat = REPEAT;
	}
	for (i = 0; i < len; ) {
		int j;
		SHA512_Init(&ctx);
		for (j = 0; j < repeat; j++) {
			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			dl_iterate_phdr(getentropy_phdr, &ctx);

			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
				HX(clock_gettime(cl[ii], &ts) == -1, ts);

			HX((pid = getpid()) == -1, pid);
			HX((pid = getsid(pid)) == -1, pid);
			HX((pid = getppid()) == -1, pid);
			HX((pid = getpgid(0)) == -1, pid);
			HX((e = getpriority(0, 0)) == -1, e);

			if (!faster) {
				ts.tv_sec = 0;
				ts.tv_nsec = 1;
				(void) nanosleep(&ts, NULL);
			}

			HX(sigpending(&sigset) == -1, sigset);
			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
			    sigset);

#if 0
			HF(main);		/* an addr in program */
#endif
			HF(getentropy);	/* an addr in this library */
			HF(printf);		/* an addr in libc */
			p = (char *)&p;
			HD(p);		/* an addr on stack */
			p = (char *)&errno;
			HD(p);		/* the addr of errno */

			if (i == 0) {
				struct sockaddr_storage ss;
				struct statvfs stvfs;
				struct termios tios;
				struct statfs stfs;
				socklen_t ssl;
				off_t off;

				/*
				 * Prime-sized mappings encourage fragmentation;
				 * thus exposing some address entropy.
				 */
				struct mm {
					size_t	npg;
					void	*p;
				} mm[] =	 {
					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
				};

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					HX(mm[m].p = mmap(NULL,
					    mm[m].npg * pgs,
					    PROT_READ|PROT_WRITE,
					    MAP_PRIVATE|MAP_ANON, -1,
					    (off_t)0), mm[m].p);
					if (mm[m].p != MAP_FAILED) {
						size_t mo;

						/* Touch some memory... */
						p = mm[m].p;
						mo = cnt %
						    (mm[m].npg * pgs - 1);
						p[mo] = 1;
						cnt += (int)((long)(mm[m].p)
						    / pgs);
					}

					/* Check cnts and times... */
					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
					    ii++) {
						HX((e = clock_gettime(cl[ii],
						    &ts)) == -1, ts);
						if (e != -1)
							cnt += (int)ts.tv_nsec;
					}

					HX((e = getrusage(RUSAGE_SELF,
					    &ru)) == -1, ru);
					if (e != -1) {
						cnt += (int)ru.ru_utime.tv_sec;
						cnt += (int)ru.ru_utime.tv_usec;
					}
				}

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					if (mm[m].p != MAP_FAILED)
						munmap(mm[m].p, mm[m].npg * pgs);
					mm[m].p = MAP_FAILED;
				}

				HX(stat(".", &st) == -1, st);
				HX(statvfs(".", &stvfs) == -1, stvfs);
				HX(statfs(".", &stfs) == -1, stfs);

				HX(stat("/", &st) == -1, st);
				HX(statvfs("/", &stvfs) == -1, stvfs);
				HX(statfs("/", &stfs) == -1, stfs);

				HX((e = fstat(0, &st)) == -1, st);
				if (e == -1) {
					if (S_ISREG(st.st_mode) ||
					    S_ISFIFO(st.st_mode) ||
					    S_ISSOCK(st.st_mode)) {
						HX(fstatvfs(0, &stvfs) == -1,
						    stvfs);
						HX(fstatfs(0, &stfs) == -1,
						    stfs);
						HX((off = lseek(0, (off_t)0,
						    SEEK_CUR)) < 0, off);
					}
					if (S_ISCHR(st.st_mode)) {
						HX(tcgetattr(0, &tios) == -1,
						    tios);
					} else if (S_ISSOCK(st.st_mode)) {
						memset(&ss, 0, sizeof ss);
						ssl = sizeof(ss);
						HX(getpeername(0,
						    (void *)&ss, &ssl) == -1,
						    ss);
					}
				}

				HX((e = getrusage(RUSAGE_CHILDREN,
				    &ru)) == -1, ru);
				if (e != -1) {
					cnt += (int)ru.ru_utime.tv_sec;
					cnt += (int)ru.ru_utime.tv_usec;
				}
			} else {
				/* Subsequent hashes absorb previous result */
				HD(results);
			}

			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HD(cnt);
		}
#ifdef HAVE_GETAUXVAL
#ifdef AT_RANDOM
		/* Not as random as you think but we take what we are given */
		p = (char *) getauxval(AT_RANDOM);
		if (p)
			HR(p, 16);
#endif
#ifdef AT_SYSINFO_EHDR
		p = (char *) getauxval(AT_SYSINFO_EHDR);
		if (p)
			HR(p, pgs);
#endif
#ifdef AT_BASE
		p = (char *) getauxval(AT_BASE);
		if (p)
			HD(p);
#endif
#endif

		SHA512_Final(results, &ctx);
		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
		i += min(sizeof(results), len - i);
	}
	memset(results, 0, sizeof results);
	if (gotdata(buf, len) == 0) {
		errno = save_errno;
		return 0;		/* satisfied */
	}
	errno = EIO;
	return -1;
}
Exemplo n.º 14
0
int journal_directory_vacuum(
                const char *directory,
                uint64_t max_use,
                usec_t max_retention_usec,
                usec_t *oldest_usec) {

        _cleanup_closedir_ DIR *d = NULL;
        int r = 0;
        struct vacuum_info *list = NULL;
        unsigned n_list = 0, i;
        size_t n_allocated = 0;
        uint64_t sum = 0, freed = 0;
        usec_t retention_limit = 0;

        assert(directory);

        if (max_use <= 0 && max_retention_usec <= 0)
                return 0;

        if (max_retention_usec > 0) {
                retention_limit = now(CLOCK_REALTIME);
                if (retention_limit > max_retention_usec)
                        retention_limit -= max_retention_usec;
                else
                        max_retention_usec = retention_limit = 0;
        }

        d = opendir(directory);
        if (!d)
                return -errno;

        for (;;) {
                int k;
                struct dirent *de;
                union dirent_storage buf;
                size_t q;
                struct stat st;
                char *p;
                unsigned long long seqnum = 0, realtime;
                sd_id128_t seqnum_id;
                bool have_seqnum;

                k = readdir_r(d, &buf.de, &de);
                if (k != 0) {
                        r = -k;
                        goto finish;
                }

                if (!de)
                        break;

                if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
                        continue;

                if (!S_ISREG(st.st_mode))
                        continue;

                q = strlen(de->d_name);

                if (endswith(de->d_name, ".journal")) {

                        /* Vacuum archived files */

                        if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8)
                                continue;

                        if (de->d_name[q-8-16-1] != '-' ||
                            de->d_name[q-8-16-1-16-1] != '-' ||
                            de->d_name[q-8-16-1-16-1-32-1] != '@')
                                continue;

                        p = strdup(de->d_name);
                        if (!p) {
                                r = -ENOMEM;
                                goto finish;
                        }

                        de->d_name[q-8-16-1-16-1] = 0;
                        if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) {
                                free(p);
                                continue;
                        }

                        if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) {
                                free(p);
                                continue;
                        }

                        have_seqnum = true;

                } else if (endswith(de->d_name, ".journal~")) {
                        unsigned long long tmp;

                        /* Vacuum corrupted files */

                        if (q < 1 + 16 + 1 + 16 + 8 + 1)
                                continue;

                        if (de->d_name[q-1-8-16-1] != '-' ||
                            de->d_name[q-1-8-16-1-16-1] != '@')
                                continue;

                        p = strdup(de->d_name);
                        if (!p) {
                                r = -ENOMEM;
                                goto finish;
                        }

                        if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) {
                                free(p);
                                continue;
                        }

                        have_seqnum = false;
                } else
                        /* We do not vacuum active files or unknown files! */
                        continue;

                if (journal_file_empty(dirfd(d), p)) {
                        /* Always vacuum empty non-online files. */

                        uint64_t size = 512UL * (uint64_t) st.st_blocks;

                        if (unlinkat(dirfd(d), p, 0) >= 0) {
                                log_info("Deleted empty journal %s/%s (%"PRIu64" bytes).",
                                         directory, p, size);
                                freed += size;
                        } else if (errno != ENOENT)
                                log_warning("Failed to delete %s/%s: %m", directory, p);

                        free(p);

                        continue;
                }

                patch_realtime(directory, p, &st, &realtime);

                GREEDY_REALLOC(list, n_allocated, n_list + 1);

                list[n_list].filename = p;
                list[n_list].usage = 512UL * (uint64_t) st.st_blocks;
                list[n_list].seqnum = seqnum;
                list[n_list].realtime = realtime;
                list[n_list].seqnum_id = seqnum_id;
                list[n_list].have_seqnum = have_seqnum;

                sum += list[n_list].usage;

                n_list ++;
        }

        qsort_safe(list, n_list, sizeof(struct vacuum_info), vacuum_compare);

        for (i = 0; i < n_list; i++) {
                struct statvfs ss;

                if (fstatvfs(dirfd(d), &ss) < 0) {
                        r = -errno;
                        goto finish;
                }

                if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
                    (max_use <= 0 || sum <= max_use))
                        break;

                if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
                        log_debug("Deleted archived journal %s/%s (%"PRIu64" bytes).",
                                  directory, list[i].filename, list[i].usage);
                        freed += list[i].usage;

                        if (list[i].usage < sum)
                                sum -= list[i].usage;
                        else
                                sum = 0;

                } else if (errno != ENOENT)
                        log_warning("Failed to delete %s/%s: %m", directory, list[i].filename);
        }

        if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec))
                *oldest_usec = list[i].realtime;

finish:
        for (i = 0; i < n_list; i++)
                free(list[i].filename);
        free(list);

        log_debug("Vacuuming done, freed %"PRIu64" bytes", freed);

        return r;
}
Exemplo n.º 15
0
int main(int argc, char *argv[]) {

    // pointer to file name string
    char *name;

    // allocate tm structure to store retrieved time
    struct tm time;

    // allocate space to hold a string with retrieved time (ASCII text)
    char asctime_str[35];

    // container for complete set of file permission bits (binary)
    unsigned int mode;

    // container for the three bits of user permissions
    unsigned int umode;

    // container for the three bits of group permissions
    unsigned int gmode;

    // container for the three bits of owner permission
    unsigned int omode;

    // human readable file permissions (ASCII text)
    char perm_bits_str[] = "---------";

    // file descriptor
    unsigned int fd;

    // structure to contain the result of the fstat call (info on this file)
    struct stat file_info;

    // structure to contain the result of the vfstat call (info on file system)
    struct statvfs fs_info;

    // used to save the return value of realpath
    char resolved_path[PATH_MAX];
    char* ret_path;

    // check number of arguments for appropriate usage
    if (2 != argc) {
        printf(" usage: %s [file_name]\n", argv[0]);
        exit(-11);
    }

    // post-condition: argv[1] contains name of file to use

    // try to open file
    fd = open(argv[1], O_RDONLY);
    if (-1 == fd) {
        perror("Failed to open read only file - ");
        exit(-1);
    }

    // use fstatvfs to learn details about the file system
    if (fstatvfs(fd, &fs_info) == 0) {
        printf("== FILE SYSTEM INFO ============================\n");
        printf(" file system fstatvfs() call successful\n");
        printf(" file system block size: %d\n", 0); // TO-DO
        printf(" max. file name length: %d\n", 0); // TO-DO
    } else {
        printf("%s: File system fstatvfs call failed\n", argv[0]);
        exit(-1);
    }

    // post-condition: maximum length of file name string is known

    // use calloc to allocate space for file name string
    name = calloc(fs_info.f_namemax, 1);

    if (NULL == name) {
        perror("Problem in calloc - ");
        exit(-1);
    }

    // copy file name into name variable using secure version of string copy
    strncpy(name, argv[1], 500);

    // use fstat to get information on specific file
    if (fstat(fd, &file_info) == 0) {
        printf("\n== FILE INFO ============================\n");
        printf(" file fstat() call successful\n");

        // mode comes from the lower 9 bits in file_info.st_mode
        mode = file_info.st_mode & 0x1FF;

        printf(" file protection bits = 0%o\n", mode);

        // umode comes from the high 3 bits in mode
        umode = 0; // TO-DO

        // gmode comes from the middle 3 bits in mode
        gmode = 0; // TO-DO

        // omode comes from the low 3 bits in mode
        omode = 0; // TO-DO

        // once you have set umode, gmode, and omode, the code below
        // will construct the right string for you and display it

        // construct string with file protection information
        if (umode & 0x4) perm_bits_str[0] = 'r';
        if (umode & 0x2) perm_bits_str[1] = 'w';
        if (umode & 0x1) perm_bits_str[2] = 'x';

        if (gmode & 0x4) perm_bits_str[3] = 'r';
        if (gmode & 0x2) perm_bits_str[4] = 'w';
        if (gmode & 0x1) perm_bits_str[5] = 'x';

        if (omode & 0x4) perm_bits_str[6] = 'r';
        if (omode & 0x2) perm_bits_str[7] = 'w';
        if (omode & 0x1) perm_bits_str[8] = 'x';

        printf(" file protection string = %s\n", perm_bits_str);

        printf(" file protection mode (u:g:o) = %o:%o:%o\n",
               umode, gmode, omode);

        printf(" owner user name = %s\n",""); // TO-DO: man getpwuid
        printf(" owner group name = %s\n", ""); // TO-DO: man getgrgid

        // TO-DO: print "mode = x", where x may be:
        // "regular file"
        // "directory"
        // "character device"
        // "block device"
        // "symbolic link"
        // "socket"
        // "fifo"
        // "unknown"

        if (S_ISREG(file_info.st_mode)) {
            printf(" mode = regular file\n");
        } else { // see TO-DO above
        }

        ret_path = realpath(name, resolved_path);
        if (NULL != ret_path)
            printf(" absolute path = %s\n", ret_path);
        else {
            perror(" couldn't resolve path");
            exit(-1);
        }

        // fill in the time the last write was made to file
        localtime_r(&(file_info.st_mtime), &time);
        asctime_r(&time, asctime_str);
        printf(" time of last modification: %s\n", asctime_str);

        fflush(stdout);
        close(fd);
        exit(0);
    }
    else
        printf(" fstat call failed\n");

    return 0;
}
Exemplo n.º 16
0
// disable shm in pulseaudio
void pulseaudio_init(void) {
	struct stat s;

	// do we have pulseaudio in the system?
	if (stat("/etc/pulse/client.conf", &s) == -1) {
		if (arg_debug)
			printf("/etc/pulse/client.conf not found\n");
		return;
	}

	// create the new user pulseaudio directory
	if (mkdir(RUN_PULSE_DIR, 0700) == -1)
		errExit("mkdir");
	// mount it nosuid, noexec, nodev
	fs_noexec(RUN_PULSE_DIR);

	// create the new client.conf file
	char *pulsecfg = NULL;
	if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1)
		errExit("asprintf");
	if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644)) // root needed
		errExit("copy_file");
	FILE *fp = fopen(pulsecfg, "a");
	if (!fp)
		errExit("fopen");
	fprintf(fp, "%s", "\nenable-shm = no\n");
	SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
	fclose(fp);
	// hand over the directory to the user
	if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700))
		errExit("set_perms");

	// create ~/.config/pulse directory if not present
	char *homeusercfg;
	if (asprintf(&homeusercfg, "%s/.config", cfg.homedir) == -1)
		errExit("asprintf");
	if (lstat(homeusercfg, &s) == -1) {
		if (create_empty_dir_as_user(homeusercfg, 0700))
			fs_logger2("create", homeusercfg);
	}
	else if (!S_ISDIR(s.st_mode)) {
		if (S_ISLNK(s.st_mode))
			fprintf(stderr, "Error: %s is a symbolic link\n", homeusercfg);
		else
			fprintf(stderr, "Error: %s is not a directory\n", homeusercfg);
		exit(1);
	}
	free(homeusercfg);

	if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1)
		errExit("asprintf");
	if (lstat(homeusercfg, &s) == -1) {
		if (create_empty_dir_as_user(homeusercfg, 0700))
			fs_logger2("create", homeusercfg);
	}
	else if (!S_ISDIR(s.st_mode)) {
		if (S_ISLNK(s.st_mode))
			fprintf(stderr, "Error: %s is a symbolic link\n", homeusercfg);
		else
			fprintf(stderr, "Error: %s is not a directory\n", homeusercfg);
		exit(1);
	}

	// if we have ~/.config/pulse mount the new directory, else set environment variable.
	if (stat(homeusercfg, &s) == 0) {
		// get a file descriptor for ~/.config/pulse, fails if there is any symlink
		int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
		if (fd == -1)
			errExit("safe_fd");
		// confirm the actual mount destination is owned by the user
		if (fstat(fd, &s) == -1)
			errExit("fstat");
		if (s.st_uid != getuid()) {
			fprintf(stderr, "Error: %s is not owned by the current user\n", homeusercfg);
			exit(1);
		}
		// preserve a read-only mount
		struct statvfs vfs;
		if (fstatvfs(fd, &vfs) == -1)
			errExit("fstatvfs");
		if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY)
			fs_rdonly(RUN_PULSE_DIR);
		// mount via the link in /proc/self/fd
		char *proc;
		if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
			errExit("asprintf");
		if (mount(RUN_PULSE_DIR, proc, "none", MS_BIND, NULL) < 0)
			errExit("mount pulseaudio");
		fs_logger2("tmpfs", homeusercfg);
		free(proc);
		close(fd);
		// check /proc/self/mountinfo to confirm the mount is ok
		MountData *mptr = get_last_mount();
		if (strcmp(mptr->dir, homeusercfg) != 0 || strcmp(mptr->fstype, "tmpfs") != 0)
			errLogExit("invalid pulseaudio mount");

		char *p;
		if (asprintf(&p, "%s/client.conf", homeusercfg) == -1)
			errExit("asprintf");
		fs_logger2("create", p);
		free(p);
	}

	else {
		// set environment
		if (setenv("PULSE_CLIENTCONFIG", pulsecfg, 1) < 0)
			errExit("setenv");
	}

	free(pulsecfg);
	free(homeusercfg);
}
Exemplo n.º 17
0
static void *filesystem_open(const char *name, int oflag, mode_t mode,
					void *context, size_t *size, int *err)
{
	struct stat stats;
	struct statvfs buf;
	const char *root_folder;
	char *folder;
	gboolean root;
	int fd = open(name, oflag, mode);
	uint64_t avail;

	if (fd < 0) {
		if (err)
			*err = -errno;
		return NULL;
	}

	if (fstat(fd, &stats) < 0) {
		if (err)
			*err = -errno;
		goto failed;
	}

	root_folder = obex_option_root_folder();
	folder = g_path_get_dirname(name);
	root = g_strcmp0(folder, root_folder);

	g_free(folder);

	if (!root || obex_option_symlinks()) {
		if (S_ISLNK(stats.st_mode)) {
			if (err)
				*err = -EPERM;
			goto failed;
		}

	}

	if (oflag == O_RDONLY) {
		if (size)
			*size = stats.st_size;
		goto done;
	}

	if (fstatvfs(fd, &buf) < 0) {
		if (err)
			*err = -errno;
		goto failed;
	}

	if (size == NULL)
		goto done;

	avail = (uint64_t) buf.f_bsize * buf.f_bavail;
	if (avail < *size) {
		if (err)
			*err = -ENOSPC;
		goto failed;
	}

done:
	if (err)
		*err = 0;

	return GINT_TO_POINTER(fd);

failed:
	close(fd);
	return NULL;
}
Exemplo n.º 18
0
int
loadblocknums(char *boot, int devfd)
{
	int		i, fd;
	struct	stat	statbuf;
	struct	statvfs	statvfsbuf;
	struct fs	*fs;
	char		*buf;
	daddr_t		blk, *ap;
	struct ufs1_dinode *ip;
	int		ndb;

	/*
	 * Open 2nd-level boot program and record the block numbers
	 * it occupies on the filesystem represented by `devfd'.
	 */

	/* Make sure the (probably new) boot file is on disk. */
	sync(); sleep(1);

	if ((fd = open(boot, O_RDONLY)) < 0)
		err(1, "open: %s", boot);

	if (fstatvfs(fd, &statvfsbuf) != 0)
		err(1, "statfs: %s", boot);

	if (strncmp(statvfsbuf.f_fstypename, "ffs",
	    sizeof(statvfsbuf.f_fstypename)) &&
	    strncmp(statvfsbuf.f_fstypename, "ufs",
	    sizeof(statvfsbuf.f_fstypename))) {
		errx(1, "%s: must be on an FFS filesystem", boot);
	}

	if (fsync(fd) != 0)
		err(1, "fsync: %s", boot);

	if (fstat(fd, &statbuf) != 0)
		err(1, "fstat: %s", boot);

	close(fd);

	/* Read superblock */
	devread(devfd, sblock, (daddr_t)(BBSIZE / DEV_BSIZE),
	    SBLOCKSIZE, "superblock");
	fs = (struct fs *)sblock;

	/* Sanity-check super-block. */
	if (fs->fs_magic != FS_UFS1_MAGIC)
		errx(1, "Bad magic number in superblock, must be UFS1");
	if (fs->fs_inopb <= 0)
		err(1, "Bad inopb=%d in superblock", fs->fs_inopb);

	/* Read inode */
	if ((buf = malloc(fs->fs_bsize)) == NULL)
		errx(1, "No memory for filesystem block");

	blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));
	devread(devfd, buf, blk, fs->fs_bsize, "inode");
	ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);

	/*
	 * Have the inode.  Figure out how many blocks we need.
	 */
	ndb = howmany(ip->di_size, fs->fs_bsize);
	if (ndb > maxblocknum)
		errx(1, "Too many blocks");
	*block_count_p = ndb;
	*block_size_p = fs->fs_bsize;
	if (verbose)
		printf("Will load %d blocks of size %d each.\n",
		    ndb, fs->fs_bsize);

	/*
	 * Get the block numbers; we don't handle fragments
	 */
	ap = ip->di_db;
	for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {
		blk = fsbtodb(fs, *ap);
		if (verbose)
			printf("%d: %d\n", i, blk);
		block_table[i] = blk;
	}
	if (ndb == 0)
		return 0;

	/*
	 * Just one level of indirections; there isn't much room
	 * for more in the 1st-level bootblocks anyway.
	 */
	blk = fsbtodb(fs, ip->di_ib[0]);
	devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
	/* XXX ondisk32 */
	ap = (int32_t *)buf;
	for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) {
		blk = fsbtodb(fs, *ap);
		if (verbose)
			printf("%d: %d\n", i, blk);
		block_table[i] = blk;
	}

	return 0;
}
Exemplo n.º 19
0
int main(void) {
    /* dummy variables to prevent null warnings */
    char path[] = "";
    char mode[] = "";
    char buf[1];
    struct stat st;
    struct statfs stfs;
    struct statvfs stvfs;
    fpos_t fpos;
    off_t off;
    struct rlimit rlim;
    glob_t glb;
    int result;
    DIR* dir;
    struct dirent direntry;
    struct dirent* pdirentry;
    struct dirent** ppdirentry;
    const struct dirent *pconstdirentry;
    dir = 0;
    result = alphasort(&pconstdirentry, &pconstdirentry);
    creat(path, 0);
    fgetpos(0, &fpos);
    fopen(path, mode);
    freopen(path, mode, 0);
    fseeko(0, 0, 0);
    fsetpos(0, &fpos);
    fstat(0, &st);
    fstatat(0, path, &st, 0);
    fstatfs(0, &stfs);
    fstatvfs(0, &stvfs);
    ftello(0);
    ftruncate(0, 0);
    ftw(path, ftw_stub, 0);
    getdirentries(0, buf, 0, &off);
    getrlimit(0, &rlim);
    glob(path, 0, glob_stub, &glb);
    lockf(0, 0, 0);
    lseek(0, 0, 0);
    lstat(path, &st);
    mkostemp(path, 0);
    mkstemp(path);
    mmap(buf, 0, 0, 0, 0, 0);
    nftw(path, nftw_stub, 0, 0);
    open(path, 0);
    open(path, 0, 0);
    openat(0, path, 0);
    openat(0, path, 0, 0);
    posix_fadvise(0, 0, 0, 0);
    posix_fallocate(0, 0, 0);
    pread(0, buf, 0, 0);
    pwrite(0, buf, 0, 0);
    readdir(dir);
    readdir_r(dir, &direntry, &pdirentry);
    scandir(path, &ppdirentry, scandir_filter_stub, scandir_compare_stub);
    sendfile(0, 0, &off, 0);
    setrlimit(0, &rlim);
    stat(path, &st);
    statfs(path, &stfs);
    statvfs(path, &stvfs);
    tmpfile();
    truncate(path, 0);
    result = versionsort(&pconstdirentry, &pconstdirentry);
    return result;
}
Exemplo n.º 20
0
static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
        _cleanup_free_ char *tmp = NULL;
        _cleanup_close_ int fd = -1;
        struct statvfs ss;
        pid_t pid = 0;
        siginfo_t si;
        int r;

        /* We want to be able to make use of btrfs-specific file
         * system features, in particular subvolumes, reflinks and
         * quota. Hence, if we detect that /var/lib/machines.raw is
         * not located on btrfs, let's create a loopback file, place a
         * btrfs file system into it, and mount it to
         * /var/lib/machines. */

        fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
        if (fd >= 0) {
                r = fd;
                fd = -1;
                return r;
        }

        if (errno != ENOENT)
                return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");

        r = tempfn_xxxxxx("/var/lib/machines.raw", NULL, &tmp);
        if (r < 0)
                return r;

        (void) mkdir_p_label("/var/lib", 0755);
        fd = open(tmp, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600);
        if (fd < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to create /var/lib/machines.raw: %m");

        if (fstatvfs(fd, &ss) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to determine free space on /var/lib/machines.raw: %m");
                goto fail;
        }

        if (ss.f_bsize * ss.f_bavail < VAR_LIB_MACHINES_FREE_MIN) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Not enough free disk space to set up /var/lib/machines.");
                goto fail;
        }

        if (ftruncate(fd, size) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to enlarge /var/lib/machines.raw: %m");
                goto fail;
        }

        pid = fork();
        if (pid < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m");
                goto fail;
        }

        if (pid == 0) {

                /* Child */

                (void) reset_all_signal_handlers();
                (void) reset_signal_mask();
                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);

                fd = safe_close(fd);

                execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL);
                if (errno == ENOENT)
                        return 99;

                _exit(EXIT_FAILURE);
        }

        r = wait_for_terminate(pid, &si);
        if (r < 0) {
                sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m");
                goto fail;
        }

        pid = 0;

        if (si.si_code != CLD_EXITED) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally.");
                goto fail;
        }
        if (si.si_status == 99) {
                r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
                goto fail;
        }
        if (si.si_status != 0) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status);
                goto fail;
        }

        r = rename_noreplace(AT_FDCWD, tmp, AT_FDCWD, "/var/lib/machines.raw");
        if (r < 0) {
                sd_bus_error_set_errnof(error, r, "Failed to move /var/lib/machines.raw into place: %m");
                goto fail;
        }

        r = fd;
        fd = -1;

        return r;

fail:
        unlink_noerrno(tmp);

        if (pid > 1)
                kill_and_sigcont(pid, SIGKILL);

        return r;
}
Exemplo n.º 21
0
static void *common_filesystem_open(const char *name, int oflag, mode_t mode,
					void *context, size_t *size, int *err,
					const uint8_t *target,
					gsize target_size,
					const char *roots[])
{
	struct stat stats;
	struct statvfs buf;
	int fd, ret;
	uint64_t avail;
	enum access_op op;

	if (oflag & O_CREAT)
		op = ACCESS_OP_CREATE;
	else if ((oflag & O_WRONLY) || (oflag & O_RDWR))
		op = ACCESS_OP_WRITE;
	else
		op = ACCESS_OP_READ;

	ret = access_check(target, target_size, op, name);
	if (ret < 0) {
		if (err)
			*err = ret;
		return NULL;
	}

	fd = open(name, oflag, mode);
	if (fd < 0) {
		if (err)
			*err = -errno;
		return NULL;
	}

	if (fstat(fd, &stats) < 0) {
		if (err)
			*err = -errno;
		goto failed;
	}

	ret = verify_path_many(name, roots);
	if (ret < 0) {
		if (err)
			*err = ret;
		goto failed;
	}

	if (oflag == O_RDONLY) {
		if (size)
			*size = stats.st_size;
		goto done;
	}

	if (fstatvfs(fd, &buf) < 0) {
		if (err)
			*err = -errno;
		goto failed;
	}

	if (size == NULL)
		goto done;

	avail = (uint64_t) buf.f_bsize * buf.f_bavail;
	if (avail < *size) {
		if (err)
			*err = -ENOSPC;
		goto failed;
	}

done:
	if (err)
		*err = 0;

	return GINT_TO_POINTER(fd);

failed:
	close(fd);
	return NULL;
}
Exemplo n.º 22
0
static int eat(const char *filename)
{

#define fail_if(cond) \
  while (cond) \
  { \
    show_error(filename); \
    if (fd != -1) \
      close(fd); \
    return -1; \
  }

#define check_io(i, j) \
  while ((size_t) (i) != (size_t) (j)) \
  { \
    if ((i) >= 0) \
      errno = EIO; \
    fail_if(1); \
  }

  const int fd = open(filename, O_RDWR);
  fail_if(fd == -1);
  const off_t file_size = lseek(fd, 0, SEEK_END);
  fail_if(file_size == -1);

  int rc;
  off_t offset;
  ssize_t r_bytes, w_bytes;

  offset = lseek(fd, 0, SEEK_SET);
  fail_if(offset == -1);

  if (block_size == 0)
  {
    struct statvfs st;
    rc = fstatvfs(fd, &st);
    fail_if(rc == -1);
    if (st.f_bsize == 0 || st.f_bsize >= block_size_limit)
    {
      errno = ERANGE;
      fail_if(1);
    }
    block_size = st.f_bsize;
  }

  const off_t n_blocks = (file_size + block_size - 1) / block_size;
  const size_t tail_size = (size_t) (1 + (file_size - 1) % block_size);

  switch (n_blocks)
  {
  case 2:
    r_bytes = read(fd, buffer, block_size);
    check_io(r_bytes, block_size);
    w_bytes = write(STDOUT_FILENO, buffer, block_size);
    check_io(w_bytes, block_size);
  case 1:
    r_bytes = read(fd, buffer, tail_size);
    check_io(r_bytes, tail_size);
    w_bytes = write(STDOUT_FILENO, buffer, (size_t) r_bytes);
    check_io(w_bytes, r_bytes);
  case 0:
    goto done;
  default:
    break;
  }

  struct stat stat;
  rc = fstat(fd, &stat);
  fail_if(rc == -1);
  if (stat.st_nlink > 1 && !opt_force)
  {
    errno = EMLINK;
    fail_if(1);
  }

  for (off_t i = 0; i < n_blocks / 2; i++)
  {
    r_bytes = read(fd, buffer, block_size);
    check_io(r_bytes, block_size);
    w_bytes = write(STDOUT_FILENO, buffer, block_size);
    check_io(w_bytes, block_size);
    if (i == 0 && opt_punch)
    {
#if HAVE_FALLOC_FL_PUNCH_HOLE
      rc = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, offset, block_size);
      if (rc == 0)
      {
        offset = 0;
        while (1)
        {
          r_bytes = read(fd, buffer, block_size);
          if (r_bytes == 0)
            break;
          offset += r_bytes;
          fail_if(r_bytes == -1);
          w_bytes = write(STDOUT_FILENO, buffer, (size_t) r_bytes);
          check_io(w_bytes, r_bytes);
          rc = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, offset);
          fail_if(rc != 0);
        }
        goto done;
      }
      else
#else
      errno = ENOTSUP;
#endif
      {
        show_error(filename);
        if (opt_punch > 1)
        {
          fprintf(stderr, "hungrycat: %s: fallocate() failed\n", filename);
          close(fd);
          return 1;
        }
        else
          fprintf(stderr, "hungrycat: %s: fallocate() failed; falling back to ftruncate()\n", filename);
      }
    }
    offset = (n_blocks - i - 1) * block_size;
    r_bytes = pread(fd, buffer, block_size, offset);
    check_io(r_bytes, (i == 0 ? tail_size : block_size));
    w_bytes = pwrite(fd, buffer, (size_t) r_bytes, i * block_size);
    check_io(r_bytes, w_bytes);
    rc = ftruncate(fd, offset);
    fail_if(rc == -1);
  }

  if ((n_blocks & 1) == 1)
  {
    r_bytes = read(fd, buffer, block_size);
    check_io(r_bytes, block_size);
    w_bytes = write(STDOUT_FILENO, buffer, block_size);
    check_io(w_bytes, block_size);
    rc = ftruncate(fd, (n_blocks / 2) * block_size);
    fail_if(rc == -1);
  }

  for (off_t i = (n_blocks / 2) - 1; i > 0; i--)
  {
    r_bytes = pread(fd, buffer, block_size, i * block_size);
    check_io(r_bytes, block_size);
    w_bytes = write(STDOUT_FILENO, buffer, block_size);
    check_io(w_bytes, block_size);
    rc = ftruncate(fd, i * block_size);
    fail_if(rc == -1);
  }

  assert(n_blocks > 0);
  r_bytes = pread(fd, buffer, tail_size, 0);
  check_io(r_bytes, tail_size);
  w_bytes = write(STDOUT_FILENO, buffer, (size_t) r_bytes);
  check_io(w_bytes, r_bytes);

done:
  rc = unlink(filename);
  fail_if(rc == -1);
  rc = close(fd);
  {
    const int fd = -1;
    fail_if(rc == -1);
  }
  return 0;

#undef fail_if

}
Exemplo n.º 23
0
static int fuse_unecm_statfs(const char *path, struct statvfs* stbuf)
{
        LOG("STATFS [%s]\n", path);

        return fstatvfs(dir_fd, stbuf);
}