18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#define _GNU_SOURCE
48c2ecf20Sopenharmony_ci#include <errno.h>
58c2ecf20Sopenharmony_ci#include <fcntl.h>
68c2ecf20Sopenharmony_ci#include <sched.h>
78c2ecf20Sopenharmony_ci#include <stdio.h>
88c2ecf20Sopenharmony_ci#include <stdlib.h>
98c2ecf20Sopenharmony_ci#include <string.h>
108c2ecf20Sopenharmony_ci#include <sys/ioctl.h>
118c2ecf20Sopenharmony_ci#include <sys/mount.h>
128c2ecf20Sopenharmony_ci#include <sys/stat.h>
138c2ecf20Sopenharmony_ci#include <sys/types.h>
148c2ecf20Sopenharmony_ci#include <unistd.h>
158c2ecf20Sopenharmony_ci#include <linux/android/binder.h>
168c2ecf20Sopenharmony_ci#include <linux/android/binderfs.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciint main(int argc, char *argv[])
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	int fd, ret, saved_errno;
218c2ecf20Sopenharmony_ci	struct binderfs_device device = { 0 };
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	ret = unshare(CLONE_NEWNS);
248c2ecf20Sopenharmony_ci	if (ret < 0) {
258c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to unshare mount namespace\n",
268c2ecf20Sopenharmony_ci			strerror(errno));
278c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
288c2ecf20Sopenharmony_ci	}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	ret = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0);
318c2ecf20Sopenharmony_ci	if (ret < 0) {
328c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to mount / as private\n",
338c2ecf20Sopenharmony_ci			strerror(errno));
348c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
358c2ecf20Sopenharmony_ci	}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	ret = mkdir("/dev/binderfs", 0755);
388c2ecf20Sopenharmony_ci	if (ret < 0 && errno != EEXIST) {
398c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to create binderfs mountpoint\n",
408c2ecf20Sopenharmony_ci			strerror(errno));
418c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
428c2ecf20Sopenharmony_ci	}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	ret = mount(NULL, "/dev/binderfs", "binder", 0, 0);
458c2ecf20Sopenharmony_ci	if (ret < 0) {
468c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to mount binderfs\n",
478c2ecf20Sopenharmony_ci			strerror(errno));
488c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
498c2ecf20Sopenharmony_ci	}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	memcpy(device.name, "my-binder", strlen("my-binder"));
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	fd = open("/dev/binderfs/binder-control", O_RDONLY | O_CLOEXEC);
548c2ecf20Sopenharmony_ci	if (fd < 0) {
558c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to open binder-control device\n",
568c2ecf20Sopenharmony_ci			strerror(errno));
578c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
588c2ecf20Sopenharmony_ci	}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	ret = ioctl(fd, BINDER_CTL_ADD, &device);
618c2ecf20Sopenharmony_ci	saved_errno = errno;
628c2ecf20Sopenharmony_ci	close(fd);
638c2ecf20Sopenharmony_ci	errno = saved_errno;
648c2ecf20Sopenharmony_ci	if (ret < 0) {
658c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to allocate new binder device\n",
668c2ecf20Sopenharmony_ci			strerror(errno));
678c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
688c2ecf20Sopenharmony_ci	}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	printf("Allocated new binder device with major %d, minor %d, and name %s\n",
718c2ecf20Sopenharmony_ci	       device.major, device.minor, device.name);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	ret = unlink("/dev/binderfs/my-binder");
748c2ecf20Sopenharmony_ci	if (ret < 0) {
758c2ecf20Sopenharmony_ci		fprintf(stderr, "%s - Failed to delete binder device\n",
768c2ecf20Sopenharmony_ci			strerror(errno));
778c2ecf20Sopenharmony_ci		exit(EXIT_FAILURE);
788c2ecf20Sopenharmony_ci	}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	/* Cleanup happens when the mount namespace dies. */
818c2ecf20Sopenharmony_ci	exit(EXIT_SUCCESS);
828c2ecf20Sopenharmony_ci}
83