Exemplo n.º 1
0
static mksh_uari_t
rndsetup(void)
{
	register uint32_t h;
	struct {
		ALLOC_ITEM alloc_INT;
		void *dataptr, *stkptr, *mallocptr;
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
		sigjmp_buf jbuf;
#endif
		struct timeval tv;
	} *bufptr;
	char *cp;

	cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
	/* clear the allocated space, for valgrind and to avoid UB */
	memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
	/* undo what alloc() did to the malloc result address */
	bufptr = (void *)(cp - sizeof(ALLOC_ITEM));
	/* PIE or something similar provides us with deltas here */
	bufptr->dataptr = &rndsetupstate;
	/* ASLR in at least Windows, Linux, some BSDs */
	bufptr->stkptr = &bufptr;
	/* randomised malloc in BSD (and possibly others) */
	bufptr->mallocptr = bufptr;
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
	/* glibc pointer guard */
	sigsetjmp(bufptr->jbuf, 1);
#endif
	/* introduce variation (and yes, second arg MBZ for portability) */
	mksh_TIME(bufptr->tv);

#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
	mprotect(((char *)bufptr) + 4096, 4096, PROT_READ | PROT_WRITE);
#endif
	h = chvt_rndsetup(bufptr, sizeof(*bufptr));

	afree(cp, APERM);
	return ((mksh_uari_t)h);
}
Exemplo n.º 2
0
static void
chvt(const Getopt *go)
{
	const char *dv = go->optarg;
	char *cp = NULL;
	int fd;

	switch (*dv) {
	case '-':
		dv = "/dev/null";
		break;
	case '!':
		++dv;
		/* FALLTHROUGH */
	default: {
		struct stat sb;

		if (stat(dv, &sb)) {
			cp = shf_smprintf("/dev/ttyC%s", dv);
			dv = cp;
			if (stat(dv, &sb)) {
				memmove(cp + 1, cp, /* /dev/tty */ 8);
				dv = cp + 1;
				if (stat(dv, &sb)) {
					errorf("%s: %s: %s", "chvt",
					    "can't find tty", go->optarg);
				}
			}
		}
		if (!(sb.st_mode & S_IFCHR))
			errorf("%s: %s: %s", "chvt", "not a char device", dv);
#ifndef MKSH_DISABLE_REVOKE_WARNING
#if HAVE_REVOKE
		if (revoke(dv))
#endif
			warningf(false, "%s: %s %s", "chvt",
			    "new shell is potentially insecure, can't revoke",
			    dv);
#endif
	    }
	}
	if ((fd = binopen2(dv, O_RDWR)) < 0) {
		sleep(1);
		if ((fd = binopen2(dv, O_RDWR)) < 0) {
			errorf("%s: %s %s", "chvt", "can't open", dv);
		}
	}
	if (go->optarg[0] != '!') {
		switch (fork()) {
		case -1:
			errorf("%s: %s %s", "chvt", "fork", "failed");
		case 0:
			break;
		default:
			exit(0);
		}
	}
	if (setsid() == -1)
		errorf("%s: %s %s", "chvt", "setsid", "failed");
	if (go->optarg[0] != '-') {
		if (ioctl(fd, TIOCSCTTY, NULL) == -1)
			errorf("%s: %s %s", "chvt", "TIOCSCTTY", "failed");
		if (tcflush(fd, TCIOFLUSH))
			errorf("%s: %s %s", "chvt", "TCIOFLUSH", "failed");
	}
	ksh_dup2(fd, 0, false);
	ksh_dup2(fd, 1, false);
	ksh_dup2(fd, 2, false);
	if (fd > 2)
		close(fd);
	rndset((unsigned long)chvt_rndsetup(go, sizeof(Getopt)));
	chvt_reinit();
}