mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-27 19:34:33 +00:00 
			
		
		
		
	Add .PLEDGE/.CPU/.MEMORY/etc. to Landlock Make 1.2
This commit is contained in:
		
							parent
							
								
									6c0bbfac4a
								
							
						
					
					
						commit
						7ab15e0b23
					
				
					 20 changed files with 494 additions and 329 deletions
				
			
		
							
								
								
									
										115
									
								
								ape/loader.c
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								ape/loader.c
									
										
									
									
									
								
							|  | @ -18,6 +18,7 @@ | |||
| ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||
| #include "ape/loader.h" | ||||
| 
 | ||||
| #define SET_EXE_FILE    0 /* needs root ;_; */ | ||||
| #define TROUBLESHOOT    0 | ||||
| #define TROUBLESHOOT_OS LINUX | ||||
| 
 | ||||
|  | @ -99,30 +100,32 @@ | |||
| #define IsOpenbsd() (SupportsOpenbsd() && os == OPENBSD) | ||||
| #define IsNetbsd()  (SupportsNetbsd() && os == NETBSD) | ||||
| 
 | ||||
| #define O_RDONLY         0 | ||||
| #define PROT_READ        1 | ||||
| #define PROT_WRITE       2 | ||||
| #define PROT_EXEC        4 | ||||
| #define MAP_SHARED       1 | ||||
| #define MAP_PRIVATE      2 | ||||
| #define MAP_FIXED        16 | ||||
| #define MAP_ANONYMOUS    (IsLinux() ? 32 : 4096) | ||||
| #define AT_EXECFN_LINUX  31 | ||||
| #define AT_EXECFN_NETBSD 2014 | ||||
| #define ELFCLASS64       2 | ||||
| #define ELFDATA2LSB      1 | ||||
| #define EM_NEXGEN32E     62 | ||||
| #define ET_EXEC          2 | ||||
| #define PT_LOAD          1 | ||||
| #define PT_DYNAMIC       2 | ||||
| #define EI_CLASS         4 | ||||
| #define EI_DATA          5 | ||||
| #define PF_X             1 | ||||
| #define PF_W             2 | ||||
| #define PF_R             4 | ||||
| #define X_OK             1 | ||||
| #define XCR0_SSE         2 | ||||
| #define XCR0_AVX         4 | ||||
| #define O_RDONLY           0 | ||||
| #define PROT_READ          1 | ||||
| #define PROT_WRITE         2 | ||||
| #define PROT_EXEC          4 | ||||
| #define MAP_SHARED         1 | ||||
| #define MAP_PRIVATE        2 | ||||
| #define MAP_FIXED          16 | ||||
| #define MAP_ANONYMOUS      (IsLinux() ? 32 : 4096) | ||||
| #define AT_EXECFN_LINUX    31 | ||||
| #define AT_EXECFN_NETBSD   2014 | ||||
| #define ELFCLASS64         2 | ||||
| #define ELFDATA2LSB        1 | ||||
| #define EM_NEXGEN32E       62 | ||||
| #define ET_EXEC            2 | ||||
| #define PT_LOAD            1 | ||||
| #define PT_DYNAMIC         2 | ||||
| #define EI_CLASS           4 | ||||
| #define EI_DATA            5 | ||||
| #define PF_X               1 | ||||
| #define PF_W               2 | ||||
| #define PF_R               4 | ||||
| #define X_OK               1 | ||||
| #define XCR0_SSE           2 | ||||
| #define XCR0_AVX           4 | ||||
| #define PR_SET_MM          35 | ||||
| #define PR_SET_MM_EXE_FILE 13 | ||||
| 
 | ||||
| #define Read32(S)                                                      \ | ||||
|   ((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \ | ||||
|  | @ -174,7 +177,10 @@ struct ElfPhdr { | |||
|   unsigned long p_align; | ||||
| }; | ||||
| 
 | ||||
| extern char ehdr[]; | ||||
| extern char _end[]; | ||||
| static void *syscall; | ||||
| static char relocated; | ||||
| static struct PathSearcher ps; | ||||
| extern char __syscall_loader[]; | ||||
| 
 | ||||
|  | @ -182,7 +188,7 @@ static int ToLower(int c) { | |||
|   return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c; | ||||
| } | ||||
| 
 | ||||
| static char *MemCpy(char *d, const char *s, unsigned long n) { | ||||
| char *MemCpy(char *d, const char *s, unsigned long n) { | ||||
|   unsigned long i = 0; | ||||
|   for (; i < n; ++i) d[i] = s[i]; | ||||
|   return d + n; | ||||
|  | @ -373,6 +379,26 @@ __attribute__((__noinline__)) static long Mmap(long addr, long size, int prot, | |||
|   return ax; | ||||
| } | ||||
| 
 | ||||
| static int MunmapLinux(const void *addr, unsigned long size) { | ||||
|   int ax; | ||||
|   asm volatile("syscall" | ||||
|                : "=a"(ax) | ||||
|                : "0"(11), "D"(addr), "S"(size) | ||||
|                : "rcx", "r11", "memory"); | ||||
|   return ax; | ||||
| } | ||||
| 
 | ||||
| static int PrctlLinux(int op, long a, long b, long c, long d) { | ||||
|   int rc; | ||||
|   asm volatile("mov\t%5,%%r10\n\t" | ||||
|                "mov\t%6,%%r8\n\t" | ||||
|                "syscall" | ||||
|                : "=a"(rc) | ||||
|                : "0"(157), "D"(op), "S"(a), "d"(b), "g"(c), "g"(d) | ||||
|                : "rcx", "r8", "r10", "r11", "memory"); | ||||
|   return rc; | ||||
| } | ||||
| 
 | ||||
| static void Emit(int os, const char *s) { | ||||
|   Write(2, s, StrLen(s), os); | ||||
| } | ||||
|  | @ -539,6 +565,23 @@ __attribute__((__noreturn__)) static void Spawn(int os, const char *exe, int fd, | |||
|   if (!code) { | ||||
|     Pexit(os, exe, 0, "ELF needs PT_LOAD phdr w/ PF_X"); | ||||
|   } | ||||
| 
 | ||||
| #if SET_EXE_FILE | ||||
|   // change /proc/pid/exe to new executable path
 | ||||
|   if (IsLinux() && relocated) { | ||||
|     MunmapLinux((char *)0x200000, (long)(_end - ehdr)); | ||||
|     PrctlLinux(PR_SET_MM, PR_SET_MM_EXE_FILE, fd, 0, 0); | ||||
|   } | ||||
| #endif | ||||
| 
 | ||||
|   if (relocated) { | ||||
|     int ax; | ||||
|     asm volatile("syscall" | ||||
|                  : "=a"(ax) | ||||
|                  : "0"(1), "D"(1), "S"("hello\n"), "d"(6) | ||||
|                  : "rcx", "r11", "memory"); | ||||
|   } | ||||
| 
 | ||||
|   Close(fd, os); | ||||
| 
 | ||||
|   // authorize only the loaded program to issue system calls. if this
 | ||||
|  | @ -584,7 +627,7 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl, | |||
|                                              struct ApeLoader *handoff) { | ||||
|   int rc; | ||||
|   long *auxv; | ||||
|   struct ElfEhdr *ehdr; | ||||
|   struct ElfEhdr *eh; | ||||
|   int c, i, fd, os, argc; | ||||
|   char *p, *exe, *prog, **argv, **envp, *page; | ||||
|   static union { | ||||
|  | @ -630,7 +673,7 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl, | |||
|     fd = handoff->fd; | ||||
|     exe = handoff->prog; | ||||
|     page = handoff->page; | ||||
|     ehdr = (struct ElfEhdr *)handoff->page; | ||||
|     eh = (struct ElfEhdr *)handoff->page; | ||||
|   } else { | ||||
| 
 | ||||
|     // detect openbsd
 | ||||
|  | @ -653,6 +696,20 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl, | |||
|       os = LINUX; | ||||
|     } | ||||
| 
 | ||||
| #if SET_EXE_FILE | ||||
|     if (IsLinux() && !relocated) { | ||||
|       char *b1 = (char *)0x200000; | ||||
|       char *b2 = (char *)0x300000; | ||||
|       void (*pApeLoader)(long, long *, char, struct ApeLoader *); | ||||
|       Mmap((long)b2, (long)(_end - ehdr), PROT_READ | PROT_WRITE | PROT_EXEC, | ||||
|            MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, os); | ||||
|       relocated = 1; | ||||
|       MemCpy(b2, b1, (long)(_end - ehdr)); | ||||
|       pApeLoader = (void *)((char *)&ApeLoader - b1 + b2); | ||||
|       pApeLoader(di, sp, dl, handoff); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     // we can load via shell, shebang, or binfmt_misc
 | ||||
|     if (argc >= 3 && !StrCmp(argv[1], "-")) { | ||||
|       // if the first argument is a hyphen then we give the user the
 | ||||
|  | @ -686,7 +743,7 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl, | |||
|     } | ||||
| 
 | ||||
|     page = u.p; | ||||
|     ehdr = &u.ehdr; | ||||
|     eh = &u.ehdr; | ||||
|   } | ||||
| 
 | ||||
| #if TROUBLESHOOT | ||||
|  | @ -726,7 +783,7 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl, | |||
|       page[i++] = c; | ||||
|     } | ||||
|     if (i >= 64 && Read32(page) == Read32("\177ELF")) { | ||||
|       Spawn(os, exe, fd, sp, page, ehdr); | ||||
|       Spawn(os, exe, fd, sp, page, eh); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,8 @@ SECTIONS { | |||
|     *(.bss) | ||||
|     . = ALIGN(4096); | ||||
|   } | ||||
|   memsz = . - ehdr; | ||||
|   _end = .; | ||||
|   memsz = _end - ehdr; | ||||
|   /DISCARD/ : { | ||||
|     *(.*) | ||||
|   } | ||||
|  |  | |||
|  | @ -45,33 +45,33 @@ int main(int argc, char *argv[]) { | |||
|          1. / 65536 * si.loads[1],    //
 | ||||
|          1. / 65536 * si.loads[2]);   //
 | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.totalram); | ||||
|   FormatMemorySize(ibuf, si.totalram, 1024); | ||||
|   printf("%-16s %s\n", "totalram", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.freeram); | ||||
|   FormatMemorySize(ibuf, si.freeram, 1024); | ||||
|   printf("%-16s %s\n", "freeram", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.sharedram); | ||||
|   FormatMemorySize(ibuf, si.sharedram, 1024); | ||||
|   printf("%-16s %s\n", "sharedram", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.bufferram); | ||||
|   FormatMemorySize(ibuf, si.bufferram, 1024); | ||||
|   printf("%-16s %s\n", "bufferram", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.totalswap); | ||||
|   FormatMemorySize(ibuf, si.totalswap, 1024); | ||||
|   printf("%-16s %s\n", "totalswap", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.freeswap); | ||||
|   FormatMemorySize(ibuf, si.freeswap, 1024); | ||||
|   printf("%-16s %s\n", "freeswap", ibuf); | ||||
| 
 | ||||
|   printf("%-16s %lu\n", "processes", si.procs); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.totalhigh); | ||||
|   FormatMemorySize(ibuf, si.totalhigh, 1024); | ||||
|   printf("%-16s %s\n", "totalhigh", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.freehigh); | ||||
|   FormatMemorySize(ibuf, si.freehigh, 1024); | ||||
|   printf("%-16s %s\n", "freehigh", ibuf); | ||||
| 
 | ||||
|   FormatMemorySize(ibuf, si.mem_unit); | ||||
|   FormatMemorySize(ibuf, si.mem_unit, 1024); | ||||
|   printf("%-16s %s\n", "mem_unit", ibuf); | ||||
| 
 | ||||
|   //
 | ||||
|  |  | |||
|  | @ -825,7 +825,7 @@ static privileged void *MemCpy(void *d, const void *s, unsigned long n) { | |||
|   return (char *)d + n; | ||||
| } | ||||
| 
 | ||||
| static privileged char *FixCpy(char p[17], uint64_t x, uint8_t k) { | ||||
| static privileged char *FixCpy(char p[17], uint64_t x, int k) { | ||||
|   while (k > 0) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15]; | ||||
|   *p = '\0'; | ||||
|   return p; | ||||
|  | @ -868,7 +868,6 @@ static privileged void Log(const char *s, ...) { | |||
| 
 | ||||
| static privileged int Prctl(int op, long a, void *b, long c, long d) { | ||||
|   int rc; | ||||
|   va_list va; | ||||
|   asm volatile("mov\t%5,%%r10\n\t" | ||||
|                "mov\t%6,%%r8\n\t" | ||||
|                "syscall" | ||||
|  |  | |||
|  | @ -19,26 +19,26 @@ | |||
| #include "libc/fmt/itoa.h" | ||||
| #include "libc/macros.internal.h" | ||||
| 
 | ||||
| static const struct { | ||||
|   char suffix; | ||||
|   uint64_t size; | ||||
| } kUnits[] = { | ||||
|     {'e', 1024ULL * 1024 * 1024 * 1024 * 1024 * 1024}, | ||||
|     {'p', 1024ULL * 1024 * 1024 * 1024 * 1024}, | ||||
|     {'t', 1024ULL * 1024 * 1024 * 1024}, | ||||
|     {'g', 1024ULL * 1024 * 1024}, | ||||
|     {'m', 1024ULL * 1024}, | ||||
|     {'k', 1024ULL}, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Represents size of memory readably. | ||||
|  * | ||||
|  * @param p is output buffer | ||||
|  * @param b should be 1024 or 1000 | ||||
|  * @return pointer to nul byte | ||||
|  */ | ||||
| char *FormatMemorySize(char *p, uint64_t x) { | ||||
| char *FormatMemorySize(char *p, uint64_t x, uint64_t b) { | ||||
|   int i, suffix; | ||||
|   struct { | ||||
|     char suffix; | ||||
|     uint64_t size; | ||||
|   } kUnits[] = { | ||||
|       {'e', b * b * b * b * b * b}, | ||||
|       {'p', b * b * b * b * b}, | ||||
|       {'t', b * b * b * b}, | ||||
|       {'g', b * b * b}, | ||||
|       {'m', b * b}, | ||||
|       {'k', b}, | ||||
|   }; | ||||
|   for (suffix = i = 0; i < ARRAYLEN(kUnits); ++i) { | ||||
|     if (x >= kUnits[i].size * 9) { | ||||
|       x = (x + kUnits[i].size / 2) / kUnits[i].size; | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ char *FormatFlex64(char[hasatleast 24], int64_t, char); | |||
| size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]); | ||||
| size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t); | ||||
| size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]); | ||||
| char *FormatMemorySize(char *, uint64_t); | ||||
| char *FormatMemorySize(char *, uint64_t, uint64_t); | ||||
| 
 | ||||
| #ifndef __STRICT_ANSI__ | ||||
| size_t int128toarray_radix10(int128_t, char *); | ||||
|  |  | |||
|  | @ -158,7 +158,7 @@ static bool IsSockaddrAllowed(struct sockaddr_storage *addr) { | |||
|   } | ||||
|   if (addr->ss_family == AF_INET) { | ||||
|     ip = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); | ||||
|     if (!IsPublicIp(ip)) { | ||||
|     if (IsPrivateIp(ip) || IsLoopbackIp(ip)) { | ||||
|       return true; | ||||
|     } else { | ||||
|       kprintf("warning: attempted to communicate with public ip " | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ void SetUpOnce(void) { | |||
| TEST(setsockopt, SO_RCVTIMEO) { | ||||
|   char buf[32]; | ||||
|   struct timeval tv = {0, 10000}; | ||||
|   struct sockaddr_in sa = {AF_INET}; | ||||
|   struct sockaddr_in sa = {AF_INET, 0, {htonl(0x7f000001)}}; | ||||
|   EXPECT_SYS(0, 3, socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); | ||||
|   EXPECT_SYS(0, 0, setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))); | ||||
|   EXPECT_SYS(0, 0, bind(3, &sa, sizeof(struct sockaddr_in))); | ||||
|  |  | |||
							
								
								
									
										188
									
								
								third_party/make/README
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										188
									
								
								third_party/make/README
									
										
									
									
										vendored
									
									
								
							|  | @ -1,188 +0,0 @@ | |||
| This directory contains the 4.3 release of GNU Make. | ||||
| 
 | ||||
| See the file NEWS for the user-visible changes from previous releases. | ||||
| In addition, there have been bugs fixed. | ||||
| 
 | ||||
| Please check the system-specific notes below for any caveats related to your | ||||
| operating system. | ||||
| 
 | ||||
| If you are trying to build GNU make from a Git clone rather than a downloaded | ||||
| source distribution, see the README.git file for instructions. | ||||
| 
 | ||||
| For source distribution building and installation instructions, see the file | ||||
| INSTALL. | ||||
| 
 | ||||
| If you need to build GNU Make and have no other 'make' program to use, you can | ||||
| use the shell script 'build.sh' instead.  To do this, first run 'configure' as | ||||
| described in INSTALL.  Then, instead of typing 'make' to build the program, | ||||
| type 'sh build.sh'.  This should compile the program in the current directory. | ||||
| Then you will have a Make program that you can use for './make install', or | ||||
| whatever else. | ||||
| 
 | ||||
| Some systems' Make programs cannot process the Makefile for GNU Make.  If you | ||||
| get errors from your system's Make when building GNU Make, try using | ||||
| 'build.sh' instead. | ||||
| 
 | ||||
| 
 | ||||
| GNU Make is free software.  See the file COPYING for copying conditions. | ||||
| GNU Make is copyright by the Free Software Foundation.  Copyright notices | ||||
| condense sequential years into a range; e.g. "1987-1994" means all years | ||||
| from 1987 to 1994 inclusive. | ||||
| 
 | ||||
| Downloading | ||||
| ----------- | ||||
| 
 | ||||
| GNU Make can be obtained in many different ways.  See a description here: | ||||
| 
 | ||||
|   http://www.gnu.org/software/software.html | ||||
| 
 | ||||
| 
 | ||||
| Documentation | ||||
| ------------- | ||||
| 
 | ||||
| GNU make is fully documented in the GNU Make manual, which is contained | ||||
| in this distribution as the file make.texinfo.  You can also find | ||||
| on-line and preformatted (PostScript and DVI) versions at the FSF's web | ||||
| site.  There is information there about ordering hardcopy documentation. | ||||
| 
 | ||||
|   http://www.gnu.org/ | ||||
|   http://www.gnu.org/doc/doc.html | ||||
|   http://www.gnu.org/manual/manual.html | ||||
| 
 | ||||
| 
 | ||||
| Development | ||||
| ----------- | ||||
| 
 | ||||
| GNU Make development is hosted by Savannah, the FSF's online development | ||||
| management tool.  Savannah is here: | ||||
| 
 | ||||
|   http://savannah.gnu.org | ||||
| 
 | ||||
| And the GNU Make development page is here: | ||||
| 
 | ||||
|   http://savannah.gnu.org/projects/make/ | ||||
| 
 | ||||
| You can find most information concerning the development of GNU Make at | ||||
| this site. | ||||
| 
 | ||||
| 
 | ||||
| Bug Reporting | ||||
| ------------- | ||||
| 
 | ||||
| You can send GNU make bug reports to <bug-make@gnu.org>.  Please see the | ||||
| section of the GNU make manual entitled 'Problems and Bugs' for | ||||
| information on submitting useful and complete bug reports. | ||||
| 
 | ||||
| You can also use the online bug tracking system in the Savannah GNU Make | ||||
| project to submit new problem reports or search for existing ones: | ||||
| 
 | ||||
|   http://savannah.gnu.org/bugs/?group=make | ||||
| 
 | ||||
| If you need help using GNU make, try these forums: | ||||
| 
 | ||||
|   help-make@gnu.org | ||||
|   help-utils@gnu.org | ||||
|   news:gnu.utils.help | ||||
|   news:gnu.utils.bug | ||||
| 
 | ||||
| 
 | ||||
| Git Access | ||||
| ---------- | ||||
| 
 | ||||
| The GNU make source repository is available via Git from the GNU Savannah Git | ||||
| server; look here for details: | ||||
| 
 | ||||
|   http://savannah.gnu.org/git/?group=make | ||||
| 
 | ||||
| Please note: you won't be able to build GNU make from Git without installing | ||||
| appropriate maintainer's tools, such as GNU m4, automake, autoconf, Perl, GNU | ||||
| make, and GCC. | ||||
| 
 | ||||
| See the README.git file for instructions on how to build GNU make once these | ||||
| tools are available.  We make no guarantees about the contents or quality of | ||||
| the latest code in the Git repository: it is not unheard of for code that is | ||||
| known to be broken to be checked in.  Use at your own risk. | ||||
| 
 | ||||
| 
 | ||||
| System-specific Notes | ||||
| --------------------- | ||||
| 
 | ||||
| It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such | ||||
| that if you compile make with 'cc -O' on AIX 3.2, it will not work | ||||
| correctly.  It is said that using 'cc' without '-O' does work. | ||||
| 
 | ||||
| The standard /bin/sh on SunOS 4.1.3_U1 and 4.1.4 is broken and cannot be | ||||
| used to configure GNU make.  Please install a different shell such as | ||||
| bash or pdksh in order to run "configure".  See this message for more | ||||
| information: | ||||
|   http://mail.gnu.org/archive/html/bug-autoconf/2003-10/msg00190.html | ||||
| 
 | ||||
| One area that is often a problem in configuration and porting is the code | ||||
| to check the system's current load average.  To make it easier to test and | ||||
| debug this code, you can do 'make check-loadavg' to see if it works | ||||
| properly on your system.  (You must run 'configure' beforehand, but you | ||||
| need not build Make itself to run this test.) | ||||
| 
 | ||||
| Another potential source of porting problems is the support for large | ||||
| files (LFS) in configure for those operating systems that provide it. | ||||
| Please report any bugs that you find in this area.  If you run into | ||||
| difficulties, then as a workaround you should be able to disable LFS by | ||||
| adding the '--disable-largefile' option to the 'configure' script. | ||||
| 
 | ||||
| On systems that support micro- and nano-second timestamp values and | ||||
| where stat(2) provides this information, GNU make will use it when | ||||
| comparing timestamps to get the most accurate possible result.  However, | ||||
| note that many current implementations of tools that *set* timestamps do | ||||
| not preserve micro- or nano-second granularity.  This means that "cp -p" | ||||
| and other similar tools (tar, etc.) may not exactly duplicate timestamps | ||||
| with micro- and nano-second granularity on some systems.  If your build | ||||
| system contains rules that depend on proper behavior of tools like "cp | ||||
| -p", you should consider using the .LOW_RESOLUTION_TIME pseudo-target to | ||||
| force make to treat them properly.  See the manual for details. | ||||
| 
 | ||||
| 
 | ||||
| Ports | ||||
| ----- | ||||
| 
 | ||||
|   - See README.customs for details on integrating GNU make with the | ||||
|     Customs distributed build environment from the Pmake distribution. | ||||
| 
 | ||||
|   - See README.VMS for details about GNU Make on OpenVMS. | ||||
| 
 | ||||
|   - See README.Amiga for details about GNU Make on AmigaDOS. | ||||
| 
 | ||||
|   - See README.W32 for details about GNU Make on Windows NT, 95, or 98. | ||||
| 
 | ||||
|   - See README.DOS for compilation instructions on MS-DOS and MS-Windows | ||||
|     using DJGPP tools. | ||||
| 
 | ||||
|     A precompiled binary of the MSDOS port of GNU Make is available as part | ||||
|     of DJGPP; see the WWW page http://www.delorie.com/djgpp/ for more | ||||
|     information. | ||||
| 
 | ||||
|     The Cygwin project maintains its own port of GNU make.  That port may have | ||||
|     patches which are not present in this version.  If you are using Cygwin | ||||
|     you should use their version of GNU make, and if you have questions about | ||||
|     it you should start by asking on those mailing lists and forums. | ||||
| 
 | ||||
| Please note there are two _separate_ ports of GNU make for Microsoft | ||||
| systems: a native Windows tool built with (for example) MSVC or Cygwin, | ||||
| and a DOS-based tool built with DJGPP.  Please be sure you are looking | ||||
| at the right README! | ||||
| 
 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copyright (C) 1988-2020 Free Software Foundation, Inc. | ||||
| This file is part of GNU Make. | ||||
| 
 | ||||
| GNU Make is free software; you can redistribute it and/or modify it under the | ||||
| terms of the GNU General Public License as published by the Free Software | ||||
| Foundation; either version 3 of the License, or (at your option) any later | ||||
| version. | ||||
| 
 | ||||
| GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY | ||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||||
| A PARTICULAR PURPOSE.  See the GNU General Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the GNU General Public License along with | ||||
| this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
							
								
								
									
										29
									
								
								third_party/make/README.cosmo
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								third_party/make/README.cosmo
									
										
									
									
										vendored
									
									
								
							|  | @ -1,12 +1,29 @@ | |||
| DESCRIPTION | ||||
| 
 | ||||
|   Landlock Make is a fork of GNU Make that adds support for automatic | ||||
|   sandboxing, resource limits, and network access restrictions. | ||||
| 
 | ||||
| ORIGIN | ||||
| 
 | ||||
|     GNU Make 4.3 | ||||
|     http://ftp.gnu.org/gnu/make/make-4.3.tar.gz | ||||
|   GNU Make 4.3 | ||||
|   http://ftp.gnu.org/gnu/make/make-4.3.tar.gz | ||||
| 
 | ||||
| LICENSE | ||||
| 
 | ||||
|   GNU GPL version 3 or later | ||||
|   http://gnu.org/licenses/gpl.html | ||||
| 
 | ||||
| LOCAL CHANGES | ||||
| 
 | ||||
|   - Remove portability torture code | ||||
|   - Add support for Landlock LSM sandboxing | ||||
|   - Add .UNSANDBOXED variable to disable it | ||||
|   - Add .UNVEIL variable which works like .EXTRA_PREREQS | ||||
|   - .INTERNET variable to allow internet access | ||||
|   - .PLEDGE variable which restricts system calls | ||||
|   - .UNVEIL variable which controls Landlock LSM | ||||
|   - .STRICT variable to disable implicit unveiling | ||||
|   - .UNSANDBOXED variable to disable pledge / unveil | ||||
|   - .CPU variable which tunes CPU rlimit in seconds | ||||
|   - .MEMORY variable for virtual memory limit, e.g. 512m | ||||
|   - .FSIZE variable which tunes max file size, e.g. 1g | ||||
|   - .NPROC variable which tunes fork() / clone() limit | ||||
|   - Do automatic setup and teardown of TMPDIR per rule | ||||
|   - Remove code that forces slow path if not using /bin/sh | ||||
|   - Remove 200,000 lines of VAX/OS2/DOS/AMIGA/etc. code | ||||
|  |  | |||
							
								
								
									
										2
									
								
								third_party/make/function.c
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								third_party/make/function.c
									
										
									
									
										vendored
									
									
								
							|  | @ -1640,7 +1640,7 @@ func_shell_base (char *o, char **argv, int trim_newlines) | |||
|     child.output.err = errfd; | ||||
|     child.environment = envp; | ||||
| 
 | ||||
|     pid = child_execute_job (&child, 1, command_argv); | ||||
|     pid = child_execute_job (&child, 1, command_argv, false); | ||||
| 
 | ||||
|     free (child.cmd_name); | ||||
|   } | ||||
|  |  | |||
							
								
								
									
										365
									
								
								third_party/make/job.c
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										365
									
								
								third_party/make/job.c
									
										
									
									
										vendored
									
									
								
							|  | @ -22,23 +22,31 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */ | |||
| /**/ | ||||
| #include "libc/assert.h" | ||||
| #include "libc/calls/calls.h" | ||||
| #include "libc/calls/pledge.h" | ||||
| #include "libc/calls/pledge.internal.h" | ||||
| #include "libc/calls/struct/bpf.h" | ||||
| #include "libc/calls/struct/filter.h" | ||||
| #include "libc/calls/struct/seccomp.h" | ||||
| #include "libc/calls/struct/sysinfo.h" | ||||
| #include "libc/calls/struct/timeval.h" | ||||
| #include "libc/dce.h" | ||||
| #include "libc/elf/def.h" | ||||
| #include "libc/elf/elf.h" | ||||
| #include "libc/elf/struct/ehdr.h" | ||||
| #include "libc/elf/struct/phdr.h" | ||||
| #include "libc/fmt/conv.h" | ||||
| #include "libc/fmt/fmt.h" | ||||
| #include "libc/fmt/itoa.h" | ||||
| #include "libc/intrin/bits.h" | ||||
| #include "libc/intrin/kprintf.h" | ||||
| #include "libc/intrin/promises.internal.h" | ||||
| #include "libc/intrin/safemacros.internal.h" | ||||
| #include "libc/log/backtrace.internal.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/log/rop.h" | ||||
| #include "libc/macros.internal.h" | ||||
| #include "libc/nexgen32e/kcpuids.h" | ||||
| #include "libc/runtime/runtime.h" | ||||
| #include "libc/runtime/stack.h" | ||||
| #include "libc/sock/sock.h" | ||||
| #include "libc/str/str.h" | ||||
| #include "libc/sysv/consts/audit.h" | ||||
|  | @ -49,6 +57,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */ | |||
| #include "libc/sysv/consts/prot.h" | ||||
| #include "libc/time/time.h" | ||||
| #include "libc/x/x.h" | ||||
| #include "third_party/libcxx/math.h" | ||||
| #include "third_party/make/commands.h" | ||||
| #include "third_party/make/dep.h" | ||||
| #include "third_party/make/os.h" | ||||
|  | @ -75,8 +84,6 @@ int batch_mode_shell = 0; | |||
| 
 | ||||
| #define WAIT_T int | ||||
| 
 | ||||
| bool g_strict; | ||||
| 
 | ||||
| /* Different systems have different requirements for pid_t.
 | ||||
|    Plus we have to support gettext string translation... Argh.  */ | ||||
| static const char * | ||||
|  | @ -377,19 +384,39 @@ child_error (struct child *child, | |||
| 
 | ||||
| /* [jart] manage temporary directories per rule */ | ||||
| 
 | ||||
| bool | ||||
| parse_bool (const char *s) | ||||
| { | ||||
|   while (isspace (*s)) | ||||
|     ++s; | ||||
|   if (isdigit (*s)) | ||||
|     return !! atoi (s); | ||||
|   return startswithi (s, "true"); | ||||
| } | ||||
| 
 | ||||
| const char * | ||||
| get_target_variable (const char *name, | ||||
|                      size_t length, | ||||
|                      struct file *file, | ||||
|                      const char *dflt) | ||||
| { | ||||
|   const struct variable *var; | ||||
|   if ((file && | ||||
|        ((var = lookup_variable_in_set (name, length, | ||||
|                                        file->variables->set)) || | ||||
|         (file->pat_variables && | ||||
|          (var = lookup_variable_in_set (name, length, | ||||
|                                         file->pat_variables->set))))) || | ||||
|       (var = lookup_variable (name, length))) | ||||
|     return variable_expand (var->value); | ||||
|   else | ||||
|     return dflt; | ||||
| } | ||||
| 
 | ||||
| const char * | ||||
| get_tmpdir (struct file *file) | ||||
| { | ||||
|   const struct variable *var; | ||||
|   if ((var = lookup_variable_in_set (STRING_SIZE_TUPLE("TMPDIR"), | ||||
|                                      file->variables->set)) || | ||||
|       (file->pat_variables && | ||||
|        (var = lookup_variable_in_set (STRING_SIZE_TUPLE("TMPDIR"), | ||||
|                                       file->pat_variables->set))) || | ||||
|       (var = lookup_variable (STRING_SIZE_TUPLE("TMPDIR")))) | ||||
|     return variable_expand (var->value); | ||||
|   else | ||||
|     return kTmpPath; | ||||
|   return get_target_variable (STRING_SIZE_TUPLE("TMPDIR"), file, 0); | ||||
| } | ||||
| 
 | ||||
| char * | ||||
|  | @ -1154,7 +1181,7 @@ start_job_command (struct child *child) | |||
|       parent_environ = environ; | ||||
|       jobserver_pre_child (flags & COMMANDS_RECURSE); | ||||
|       child->pid = child_execute_job ((struct childbase *)child, | ||||
|                                       child->good_stdin, argv); | ||||
|                                       child->good_stdin, argv, true); | ||||
|       environ = parent_environ; /* Restore value child may have clobbered.  */ | ||||
|       jobserver_post_child (flags & COMMANDS_RECURSE); | ||||
|     } | ||||
|  | @ -1277,7 +1304,8 @@ new_job (struct file *file) | |||
|   c->sh_batch_file = NULL; | ||||
| 
 | ||||
|   /* [jart] manage temporary directories per rule */ | ||||
|   if ((c->tmpdir = new_tmpdir (get_tmpdir (file), file))) | ||||
|   if ((c->tmpdir = get_tmpdir (file)) && | ||||
|       (c->tmpdir = new_tmpdir (c->tmpdir, file))) | ||||
|     { | ||||
|       var = define_variable_for_file ("TMPDIR", 6, c->tmpdir, | ||||
|                                       o_override, 0, file); | ||||
|  | @ -1764,22 +1792,98 @@ unveil_variable (const struct variable *var) | |||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
| Vartoi (const struct variable *var) | ||||
| int | ||||
| get_base_cpu_freq_mhz (void) | ||||
| { | ||||
|   return var && atoi (variable_expand (var->value)); | ||||
|   return KCPUIDS(16H, EAX) & 0x7fff; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| set_cpu_limit (int secs) | ||||
| { | ||||
|   int mhz, lim; | ||||
|   struct rlimit rlim; | ||||
|   if (secs <= 0) return; | ||||
|   if (IsWindows()) return; | ||||
|   if (!(mhz = get_base_cpu_freq_mhz())) return; | ||||
|   lim = ceil(3100. / mhz * secs); | ||||
|   rlim.rlim_cur = lim; | ||||
|   rlim.rlim_max = lim + 1; | ||||
|   if (setrlimit(RLIMIT_CPU, &rlim) == -1) | ||||
|     { | ||||
|       if (getrlimit(RLIMIT_CPU, &rlim) == -1) | ||||
|         return; | ||||
|       if (lim < rlim.rlim_cur) | ||||
|         { | ||||
|           rlim.rlim_cur = lim; | ||||
|           setrlimit(RLIMIT_CPU, &rlim); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| set_fsz_limit (long n) | ||||
| { | ||||
|   struct rlimit rlim; | ||||
|   if (n <= 0) return; | ||||
|   if (IsWindows()) return; | ||||
|   rlim.rlim_cur = n; | ||||
|   rlim.rlim_max = n << 1; | ||||
|   if (setrlimit(RLIMIT_FSIZE, &rlim) == -1) | ||||
|     { | ||||
|       if (getrlimit(RLIMIT_FSIZE, &rlim) == -1) | ||||
|         return; | ||||
|       rlim.rlim_cur = n; | ||||
|       setrlimit(RLIMIT_FSIZE, &rlim); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| set_mem_limit (long n) | ||||
| { | ||||
|   struct rlimit rlim = {n, n}; | ||||
|   if (n <= 0) return; | ||||
|   if (IsWindows() || IsXnu()) return; | ||||
|   setrlimit(RLIMIT_AS, &rlim); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| set_pro_limit (long n) | ||||
| { | ||||
|   struct rlimit rlim = {n, n}; | ||||
|   if (n <= 0) return; | ||||
|   setrlimit(RLIMIT_NPROC, &rlim); | ||||
| } | ||||
| 
 | ||||
| static struct sysinfo g_sysinfo; | ||||
| 
 | ||||
| __attribute__((__constructor__)) static void | ||||
| get_sysinfo (void) | ||||
| { | ||||
|   int e = errno; | ||||
|   sysinfo (&g_sysinfo); | ||||
|   errno = e; | ||||
| } | ||||
| 
 | ||||
| static bool internet; | ||||
| static char *promises; | ||||
| 
 | ||||
| /* POSIX:
 | ||||
|    Create a child process executing the command in ARGV. | ||||
|    Returns the PID or -1.  */ | ||||
| pid_t | ||||
| child_execute_job (struct childbase *child, int good_stdin, char **argv) | ||||
| child_execute_job (struct childbase *child, | ||||
|                    int good_stdin, | ||||
|                    char **argv, | ||||
|                    bool is_build_rule) | ||||
| { | ||||
|   const int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); | ||||
|   struct dep *d; | ||||
|   bool strict; | ||||
|   bool sandboxed; | ||||
|   bool unsandboxed; | ||||
|   struct child *c; | ||||
|   unsigned long ipromises; | ||||
|   char pathbuf[PATH_MAX]; | ||||
|   char outpathbuf[PATH_MAX]; | ||||
|   int fdout = FD_STDOUT; | ||||
|  | @ -1808,28 +1912,145 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) | |||
|   if (stack_limit.rlim_cur) | ||||
|     setrlimit (RLIMIT_STACK, &stack_limit); | ||||
| 
 | ||||
|   g_strict = Vartoi (lookup_variable (STRING_SIZE_TUPLE (".STRICT"))); | ||||
| 
 | ||||
|   intptr_t loc = (intptr_t)child;  /* we can cast if it's on the heap ;_; */ | ||||
|   if (!(GetStackAddr() < loc && loc < GetStackAddr() + GetStackSize())) { | ||||
|   /* Tell build rules apart from $(shell foo).  */ | ||||
|   if (is_build_rule) { | ||||
|     c = (struct child *)child; | ||||
|   } else { | ||||
|     c = 0; | ||||
|   } | ||||
| 
 | ||||
|   sandboxed = ( | ||||
|       !Vartoi (lookup_variable | ||||
|                (STRING_SIZE_TUPLE(".UNSANDBOXED"))) && | ||||
|       (!c || !Vartoi (lookup_variable_in_set | ||||
|                       (STRING_SIZE_TUPLE(".UNSANDBOXED"), | ||||
|                        c->file->variables->set))) && | ||||
|       (!c || !c->file->pat_variables || | ||||
|        !Vartoi (lookup_variable_in_set | ||||
|                 (STRING_SIZE_TUPLE(".UNSANDBOXED"), | ||||
|                  c->file->pat_variables->set)))); | ||||
|   internet = parse_bool (get_target_variable | ||||
|                          (STRING_SIZE_TUPLE(".INTERNET"), | ||||
|                           c ? c->file : 0, "0")); | ||||
| 
 | ||||
|   /* resolve command into executable path */ | ||||
|   if (!g_strict || !sandboxed) | ||||
|   unsandboxed = parse_bool (get_target_variable | ||||
|                             (STRING_SIZE_TUPLE(".UNSANDBOXED"), | ||||
|                              c ? c->file : 0, "0")); | ||||
| 
 | ||||
|   if (c) | ||||
|     { | ||||
|       sandboxed = !unsandboxed; | ||||
|       strict = parse_bool (get_target_variable | ||||
|                            (STRING_SIZE_TUPLE(".STRICT"), | ||||
|                             c->file, "0")); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       sandboxed = false; | ||||
|       strict = false; | ||||
|     } | ||||
| 
 | ||||
|   if (!unsandboxed) | ||||
|     { | ||||
|       promises = emptytonull (get_target_variable | ||||
|                               (STRING_SIZE_TUPLE(".PLEDGE"), | ||||
|                                c ? c->file : 0, 0)); | ||||
|       if (promises) | ||||
|         promises = xstrdup (promises); | ||||
|       if (ParsePromises (promises, &ipromises)) | ||||
|         { | ||||
|           OSS (error, NILF, "%s: invalid .PLEDGE string: %s", | ||||
|                argv[0], strerror (errno)); | ||||
|           _Exit (127); | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       promises = NULL; | ||||
|       ipromises = 0; | ||||
|     } | ||||
| 
 | ||||
|   DB (DB_JOBS,  | ||||
|       (_("Executing %s for %s%s%s%s\n"), | ||||
|        argv[0], c ? c->file->name : "$(shell)", | ||||
|        sandboxed ? " with sandboxing" : " without sandboxing", | ||||
|        strict ? " in .STRICT mode" : "", | ||||
|        internet ? " with internet access" : "")); | ||||
| 
 | ||||
|   /* [jart] Set cpu seconds quota.  */ | ||||
|   if ((s = get_target_variable (STRING_SIZE_TUPLE(".CPU"), | ||||
|                                 c ? c->file : 0, 0))) | ||||
|     { | ||||
|       int secs; | ||||
|       secs = atoi (s); | ||||
|       DB (DB_JOBS, (_("Setting cpu limit of %d seconds\n"), secs)); | ||||
|       set_cpu_limit (secs); | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] Set virtual memory quota.  */ | ||||
|   if ((s = get_target_variable (STRING_SIZE_TUPLE(".MEMORY"), | ||||
|                                 c ? c->file : 0, 0))) | ||||
|     { | ||||
|       long bytes; | ||||
|       char buf[16]; | ||||
|       if (!strchr (s, '%')) | ||||
|         bytes = sizetol (s, 1024); | ||||
|       else | ||||
|         bytes = strtod (s, 0) / 100. * g_sysinfo.totalram; | ||||
|       DB (DB_JOBS, (_("Setting virtual memory limit of %s\n"), | ||||
|                     (FormatMemorySize (buf, bytes, 1024), buf))); | ||||
|       set_mem_limit (bytes); | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] Set file size limit.  */ | ||||
|   if ((s = get_target_variable (STRING_SIZE_TUPLE(".FSIZE"), | ||||
|                                 c ? c->file : 0, 0))) | ||||
|     { | ||||
|       long bytes; | ||||
|       char buf[16]; | ||||
|       bytes = sizetol (s, 1000); | ||||
|       DB (DB_JOBS, (_("Setting file size limit of %s\n"), | ||||
|                     (FormatMemorySize (buf, bytes, 1000), buf))); | ||||
|       set_fsz_limit (bytes); | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] Set process limit.  */ | ||||
|   if ((s = get_target_variable (STRING_SIZE_TUPLE(".NPROC"), | ||||
|                                 c ? c->file : 0, 0))) | ||||
|     { | ||||
|       int procs; | ||||
|       if ((procs = atoi (s)) > 0) | ||||
|         { | ||||
|           DB (DB_JOBS, (_("Setting process limit to %d + %d preexisting\n"), | ||||
|                         procs, g_sysinfo.procs)); | ||||
|           set_pro_limit (procs + g_sysinfo.procs); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] Prevent builds from talking to the Internet.  */ | ||||
|   if (internet) | ||||
|     DB (DB_JOBS, (_("Allowing Internet access\n"))); | ||||
|   else if (!(~ipromises & (1ul << PROMISE_INET)) && | ||||
|            !(~ipromises & (1ul << PROMISE_DNS))) | ||||
|     DB (DB_JOBS, (_("Internet access will be blocked by pledge\n"))); | ||||
|   else | ||||
|     { | ||||
|       e = errno; | ||||
|       if (!nointernet()) | ||||
|         DB (DB_JOBS, (_("Blocked Internet access with seccomp ptrace\n"))); | ||||
|       else | ||||
|         { | ||||
|           if (errno = EPERM) | ||||
|             { | ||||
|               errno = e; | ||||
|               DB (DB_JOBS, (_("Can't block Internet if already traced\n"))); | ||||
|             } | ||||
|           else if (errno == ENOSYS) | ||||
|             { | ||||
|               errno = e; | ||||
|               DB (DB_JOBS, (_("Need SECCOMP ptrace() to block Internet\n"))); | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               OSS (error, NILF, "%s: failed to block internet access: %s", | ||||
|                    argv[0], strerror (errno)); | ||||
|               _Exit (127); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] Resolve command into executable path.  */ | ||||
|   if (!strict || !sandboxed) | ||||
|     { | ||||
|       if ((s = commandv (argv[0], pathbuf, sizeof (pathbuf)))) | ||||
|         argv[0] = s; | ||||
|  | @ -1841,15 +2062,13 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* [jart] sandbox command based on prerequisites */ | ||||
|   /* [jart] Sandbox build rule commands based on prerequisites.  */ | ||||
|   if (c) | ||||
|     { | ||||
|       errno = 0; | ||||
|       if (sandboxed) | ||||
|         { | ||||
|           DB (DB_JOBS, (_("Sandboxing %s\n"), c->file->name)); | ||||
| 
 | ||||
|           if (!g_strict && argv[0][0] == '/' && IsDynamicExecutable (argv[0])) | ||||
|           if (!strict && argv[0][0] == '/' && IsDynamicExecutable (argv[0])) | ||||
|             { | ||||
|               /*
 | ||||
|                * weaken sandbox if user is using dynamic shared lolbjects | ||||
|  | @ -1883,6 +2102,8 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) | |||
|                * only if the ape loader exists on a well-known path. | ||||
|                */ | ||||
|               e = errno; | ||||
|               DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"), | ||||
|                             "/usr/bin/ape", "rx")); | ||||
|               if (unveil ("/usr/bin/ape", "rx") == -1) | ||||
|                 { | ||||
|                   char *s, *t; | ||||
|  | @ -1902,15 +2123,15 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|           /* unveil executable */ | ||||
|           /* Unveil executable.  */ | ||||
|           RETURN_ON_ERROR (Unveil (argv[0], "rx")); | ||||
| 
 | ||||
|           /* unveil temporary directory */ | ||||
|           /* Unveil temporary directory.  */ | ||||
|           if (c->tmpdir) | ||||
|             RETURN_ON_ERROR (Unveil (c->tmpdir, "rwcx")); | ||||
| 
 | ||||
|           /* unveil lazy mode files */ | ||||
|           if (!g_strict) | ||||
|           /* Unveil lazy mode files.  */ | ||||
|           if (!strict) | ||||
|             { | ||||
|               RETURN_ON_ERROR (Unveil ("/tmp", "rwc")); | ||||
|               RETURN_ON_ERROR (Unveil ("/dev/zero", "r")); | ||||
|  | @ -1922,6 +2143,50 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) | |||
|               RETURN_ON_ERROR (Unveil ("/etc/hosts", "r")); | ||||
|             } | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = tmppath.  */ | ||||
|           if (!strict && promises && (~ipromises & (1ul << PROMISE_TMPPATH))) | ||||
|             RETURN_ON_ERROR (Unveil ("/tmp", "rwc")); | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = vminfo.  */ | ||||
|           if (promises && (~ipromises & (1ul << PROMISE_VMINFO))) | ||||
|             { | ||||
|               RETURN_ON_ERROR (Unveil ("/proc/stat", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/proc/meminfo", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/proc/cpuinfo", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/proc/diskstats", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/proc/self/maps", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/sys/devices/system/cpu", "r")); | ||||
|             } | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = tty.  */ | ||||
|           if (promises && (~ipromises & (1ul << PROMISE_TTY))) | ||||
|             { | ||||
|               RETURN_ON_ERROR (Unveil (ttyname(0), "rw")); | ||||
|               RETURN_ON_ERROR (Unveil ("/dev/tty", "rw")); | ||||
|               RETURN_ON_ERROR (Unveil ("/dev/console", "rw")); | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/terminfo", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/usr/lib/terminfo", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/usr/share/terminfo", "r")); | ||||
|             } | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = dns.  */ | ||||
|           if (promises && (~ipromises & (1ul << PROMISE_DNS))) | ||||
|             { | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/hosts", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/hostname", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/services", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/protocols", "r")); | ||||
|               RETURN_ON_ERROR (Unveil ("/etc/resolv.conf", "r")); | ||||
|             } | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = inet.  */ | ||||
|           if (promises && (~ipromises & (1ul << PROMISE_INET))) | ||||
|             RETURN_ON_ERROR (Unveil ("/etc/ssl/certs/ca-certificates.crt", "r")); | ||||
| 
 | ||||
|           /* Unveil .PLEDGE = rpath.  */ | ||||
|           if (promises && (~ipromises & (1ul << PROMISE_INET))) | ||||
|             RETURN_ON_ERROR (Unveil ("/proc/filesystems", "r")); | ||||
| 
 | ||||
|           /*
 | ||||
|            * unveils target output file | ||||
|            * | ||||
|  | @ -2017,6 +2282,20 @@ exec_command (char **argv, char **envp) | |||
|   /* Be the user, permanently.  */ | ||||
|   child_access (); | ||||
| 
 | ||||
|   /* Restrict system calls.  */ | ||||
|   if (promises) | ||||
|     { | ||||
|       __pledge_mode = PLEDGE_PENALTY_RETURN_EPERM; | ||||
|       DB (DB_JOBS, (_("Pledging %s\n"), promises)); | ||||
|       promises = xstrcat (promises, " prot_exec exec"); | ||||
|       if (pledge (promises, promises)) | ||||
|         { | ||||
|           OSS (error, NILF, "pledge(%s) failed: %s", | ||||
|                promises, strerror (errno)); | ||||
|           _Exit (127); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* Run the program.  */ | ||||
|   environ = envp; | ||||
|   execv (argv[0], argv); | ||||
|  |  | |||
							
								
								
									
										2
									
								
								third_party/make/job.h
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								third_party/make/job.h
									
										
									
									
										vendored
									
									
								
							|  | @ -71,7 +71,7 @@ void start_waiting_jobs (void); | |||
| char **construct_command_argv (char *line, char **restp, struct file *file, | ||||
|                                int cmd_flags, char** batch_file); | ||||
| 
 | ||||
| pid_t child_execute_job (struct childbase *child, int good_stdin, char **argv); | ||||
| pid_t child_execute_job (struct childbase *, int, char **, bool); | ||||
| 
 | ||||
| #ifdef _AMIGA | ||||
| void exec_command (char **argv) NORETURN; | ||||
|  |  | |||
							
								
								
									
										50
									
								
								third_party/make/main.c
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								third_party/make/main.c
									
										
									
									
										vendored
									
									
								
							|  | @ -14,40 +14,36 @@ A PARTICULAR PURPOSE.  See the GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License along with | ||||
| this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* clang-format off */ | ||||
| #include "third_party/make/makeint.inc" | ||||
| #include "third_party/make/os.h" | ||||
| /**/ | ||||
| #include "third_party/make/filedef.h" | ||||
| #include "third_party/make/os.h" | ||||
| /**/ | ||||
| #include "third_party/make/dep.h" | ||||
| #include "third_party/make/variable.h" | ||||
| #include "third_party/make/job.h" | ||||
| #include "third_party/make/variable.h" | ||||
| /**/ | ||||
| #include "third_party/make/commands.h" | ||||
| #include "third_party/make/rule.h" | ||||
| #include "third_party/make/debug.h" | ||||
| #include "libc/runtime/stack.h" | ||||
| #include "libc/limits.h" | ||||
| #include "libc/sysv/consts/sig.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/sock/sock.h" | ||||
| #include "libc/dce.h" | ||||
| #include "libc/calls/syscall_support-sysv.internal.h" | ||||
| #include "libc/calls/struct/seccomp.h" | ||||
| #include "libc/calls/struct/bpf.h" | ||||
| #include "libc/sysv/consts/audit.h" | ||||
| #include "libc/calls/struct/seccomp.h" | ||||
| #include "libc/sysv/consts/pr.h" | ||||
| #include "third_party/make/rule.h" | ||||
| /**/ | ||||
| #include "libc/calls/calls.h" | ||||
| #include "libc/macros.internal.h" | ||||
| #include "libc/stdio/stdio.h" | ||||
| #include "libc/calls/struct/bpf.h" | ||||
| #include "libc/calls/struct/filter.h" | ||||
| #include "libc/calls/struct/seccomp.h" | ||||
| #include "libc/calls/syscall_support-sysv.internal.h" | ||||
| #include "libc/dce.h" | ||||
| #include "libc/limits.h" | ||||
| #include "libc/macros.internal.h" | ||||
| #include "libc/runtime/runtime.h" | ||||
| #include "libc/runtime/runtime.h" | ||||
| #include "libc/runtime/runtime.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/log/log.h" | ||||
| #include "libc/runtime/stack.h" | ||||
| #include "libc/sock/sock.h" | ||||
| #include "libc/stdio/stdio.h" | ||||
| #include "libc/sysv/consts/audit.h" | ||||
| #include "libc/sysv/consts/pr.h" | ||||
| #include "libc/sysv/consts/sig.h" | ||||
| #include "third_party/make/getopt.h" | ||||
| // clang-format off
 | ||||
| 
 | ||||
| STATIC_STACK_SIZE(0x200000);  // 2mb stack
 | ||||
| 
 | ||||
|  | @ -985,10 +981,6 @@ main (int argc, char **argv, char **envp) | |||
|   unsigned int syncing = 0; | ||||
|   int argv_slots; | ||||
| 
 | ||||
|   // block internet access
 | ||||
|   if (!getenv("MAKE_RESTARTS")) | ||||
|     nointernet (); | ||||
| 
 | ||||
|   /* Useful for attaching debuggers, etc.  */ | ||||
|   SPIN ("main-entry"); | ||||
| 
 | ||||
|  | @ -2982,7 +2974,7 @@ print_version (void) | |||
|     /* Do it only once.  */ | ||||
|     return; | ||||
| 
 | ||||
|   printf ("%sLandlock Make 1.1.1 (GNU Make %s)\n", precede, version_string); | ||||
|   printf ("%sLandlock Make 1.2 (GNU Make %s)\n", precede, version_string); | ||||
| 
 | ||||
|   if (!remote_description || *remote_description == '\0') | ||||
|     printf (_("%sBuilt for %s\n"), precede, make_host); | ||||
|  |  | |||
|  | @ -254,7 +254,9 @@ static int OpMunmap(struct Machine *m, int64_t virt, uint64_t size) { | |||
| 
 | ||||
| static int64_t OpMmap(struct Machine *m, int64_t virt, size_t size, int prot, | ||||
|                       int flags, int fd, int64_t offset) { | ||||
|   int e; | ||||
|   void *tmp; | ||||
|   ssize_t rc; | ||||
|   uint64_t key; | ||||
|   VERBOSEF("MMAP%s %012lx %,ld %#x %#x %d %#lx", GetSimulated(), virt, size, | ||||
|            prot, flags, fd, offset); | ||||
|  | @ -277,7 +279,13 @@ static int64_t OpMmap(struct Machine *m, int64_t virt, size_t size, int prot, | |||
|       if (fd != -1 && !(flags & MAP_ANONYMOUS)) { | ||||
|         /* TODO: lazy file mappings */ | ||||
|         CHECK_NOTNULL((tmp = malloc(size))); | ||||
|         CHECK_EQ(size, pread(fd, tmp, size, offset)); | ||||
|         for (e = errno;;) { | ||||
|           rc = pread(fd, tmp, size, offset); | ||||
|           if (rc != -1) break; | ||||
|           CHECK_EQ(EINTR, errno); | ||||
|           errno = e; | ||||
|         } | ||||
|         CHECK_EQ(size, rc); | ||||
|         VirtualRecvWrite(m, virt, tmp, size); | ||||
|         free(tmp); | ||||
|       } | ||||
|  |  | |||
|  | @ -7104,7 +7104,7 @@ static void HandleShutdown(void) { | |||
| } | ||||
| 
 | ||||
| // this function coroutines with linenoise
 | ||||
| static int EventLoop(int ms) { | ||||
| int EventLoop(int ms) { | ||||
|   struct timespec t; | ||||
|   DEBUGF("(repl) event loop"); | ||||
|   while (!terminated) { | ||||
|  |  | |||
|  | @ -7,9 +7,9 @@ | |||
| │   • http://creativecommons.org/publicdomain/zero/1.0/            │
 | ||||
| ╚─────────────────────────────────────────────────────────────────*/ | ||||
| #endif | ||||
| #include "libc/intrin/bits.h" | ||||
| #include "libc/calls/internal.h" | ||||
| #include "libc/fmt/itoa.h" | ||||
| #include "libc/intrin/bits.h" | ||||
| #include "libc/macros.internal.h" | ||||
| #include "libc/runtime/memtrack.internal.h" | ||||
| #include "libc/stdio/stdio.h" | ||||
|  | @ -30,7 +30,7 @@ uint64_t last; | |||
| 
 | ||||
| void plan2(uint64_t addr, uint64_t end, const char *name) { | ||||
|   char sz[32]; | ||||
|   FormatMemorySize(sz, end-addr+1); | ||||
|   FormatMemorySize(sz, end-addr+1, 1024); | ||||
|   printf("%08x-%08x %-6s %s\n", addr>>16, end>>16, sz, name); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue