1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #define _GNU_SOURCE |
4 | #include <errno.h> |
5 | #include <fcntl.h> |
6 | #include <sched.h> |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <string.h> |
10 | #include <sys/ioctl.h> |
11 | #include <sys/mount.h> |
12 | #include <sys/stat.h> |
13 | #include <sys/types.h> |
14 | #include <unistd.h> |
15 | #include <linux/android/binder.h> |
16 | #include <linux/android/binderfs.h> |
17 | |
18 | int main(int argc, char *argv[]) |
19 | { |
20 | int fd, ret, saved_errno; |
21 | struct binderfs_device device = { 0 }; |
22 | |
23 | ret = unshare(CLONE_NEWNS); |
24 | if (ret < 0) { |
25 | fprintf(stderr, format: "%s - Failed to unshare mount namespace\n" , |
26 | strerror(errno)); |
27 | exit(EXIT_FAILURE); |
28 | } |
29 | |
30 | ret = mount(NULL, dir: "/" , NULL, MS_REC | MS_PRIVATE, data: 0); |
31 | if (ret < 0) { |
32 | fprintf(stderr, format: "%s - Failed to mount / as private\n" , |
33 | strerror(errno)); |
34 | exit(EXIT_FAILURE); |
35 | } |
36 | |
37 | ret = mkdir(path: "/dev/binderfs" , mode: 0755); |
38 | if (ret < 0 && errno != EEXIST) { |
39 | fprintf(stderr, format: "%s - Failed to create binderfs mountpoint\n" , |
40 | strerror(errno)); |
41 | exit(EXIT_FAILURE); |
42 | } |
43 | |
44 | ret = mount(NULL, dir: "/dev/binderfs" , fstype: "binder" , rwflag: 0, data: 0); |
45 | if (ret < 0) { |
46 | fprintf(stderr, format: "%s - Failed to mount binderfs\n" , |
47 | strerror(errno)); |
48 | exit(EXIT_FAILURE); |
49 | } |
50 | |
51 | memcpy(dest: device.name, src: "my-binder" , n: strlen(s: "my-binder" )); |
52 | |
53 | fd = open(file: "/dev/binderfs/binder-control" , O_RDONLY | O_CLOEXEC); |
54 | if (fd < 0) { |
55 | fprintf(stderr, format: "%s - Failed to open binder-control device\n" , |
56 | strerror(errno)); |
57 | exit(EXIT_FAILURE); |
58 | } |
59 | |
60 | ret = ioctl(fd: fd, BINDER_CTL_ADD, &device); |
61 | saved_errno = errno; |
62 | close(fd: fd); |
63 | errno = saved_errno; |
64 | if (ret < 0) { |
65 | fprintf(stderr, format: "%s - Failed to allocate new binder device\n" , |
66 | strerror(errno)); |
67 | exit(EXIT_FAILURE); |
68 | } |
69 | |
70 | printf(format: "Allocated new binder device with major %d, minor %d, and name %s\n" , |
71 | device.major, device.minor, device.name); |
72 | |
73 | ret = unlink(name: "/dev/binderfs/my-binder" ); |
74 | if (ret < 0) { |
75 | fprintf(stderr, format: "%s - Failed to delete binder device\n" , |
76 | strerror(errno)); |
77 | exit(EXIT_FAILURE); |
78 | } |
79 | |
80 | /* Cleanup happens when the mount namespace dies. */ |
81 | exit(EXIT_SUCCESS); |
82 | } |
83 | |