18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2019 Alexey Dobriyan <adobriyan@gmail.com> 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, and distribute this software for any 58c2ecf20Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 68c2ecf20Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98c2ecf20Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108c2ecf20Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 118c2ecf20Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128c2ecf20Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 138c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 148c2ecf20Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci/* Test that pointing #! script interpreter to self doesn't recurse. */ 178c2ecf20Sopenharmony_ci#include <errno.h> 188c2ecf20Sopenharmony_ci#include <sched.h> 198c2ecf20Sopenharmony_ci#include <stdio.h> 208c2ecf20Sopenharmony_ci#include <string.h> 218c2ecf20Sopenharmony_ci#include <sys/types.h> 228c2ecf20Sopenharmony_ci#include <sys/stat.h> 238c2ecf20Sopenharmony_ci#include <fcntl.h> 248c2ecf20Sopenharmony_ci#include <sys/mount.h> 258c2ecf20Sopenharmony_ci#include <unistd.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciint main(void) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci if (unshare(CLONE_NEWNS) == -1) { 308c2ecf20Sopenharmony_ci if (errno == ENOSYS || errno == EPERM) { 318c2ecf20Sopenharmony_ci fprintf(stderr, "error: unshare, errno %d\n", errno); 328c2ecf20Sopenharmony_ci return 4; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci fprintf(stderr, "error: unshare, errno %d\n", errno); 358c2ecf20Sopenharmony_ci return 1; 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) { 388c2ecf20Sopenharmony_ci fprintf(stderr, "error: mount '/', errno %d\n", errno); 398c2ecf20Sopenharmony_ci return 1; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci /* Require "exec" filesystem. */ 428c2ecf20Sopenharmony_ci if (mount(NULL, "/tmp", "ramfs", 0, NULL) == -1) { 438c2ecf20Sopenharmony_ci fprintf(stderr, "error: mount ramfs, errno %d\n", errno); 448c2ecf20Sopenharmony_ci return 1; 458c2ecf20Sopenharmony_ci } 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define FILENAME "/tmp/1" 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci int fd = creat(FILENAME, 0700); 508c2ecf20Sopenharmony_ci if (fd == -1) { 518c2ecf20Sopenharmony_ci fprintf(stderr, "error: creat, errno %d\n", errno); 528c2ecf20Sopenharmony_ci return 1; 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci#define S "#!" FILENAME "\n" 558c2ecf20Sopenharmony_ci if (write(fd, S, strlen(S)) != strlen(S)) { 568c2ecf20Sopenharmony_ci fprintf(stderr, "error: write, errno %d\n", errno); 578c2ecf20Sopenharmony_ci return 1; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci close(fd); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci int rv = execve(FILENAME, NULL, NULL); 628c2ecf20Sopenharmony_ci if (rv == -1 && errno == ELOOP) { 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci } 658c2ecf20Sopenharmony_ci fprintf(stderr, "error: execve, rv %d, errno %d\n", rv, errno); 668c2ecf20Sopenharmony_ci return 1; 678c2ecf20Sopenharmony_ci} 68