From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 22169 invoked from network); 4 May 2023 19:14:29 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 4 May 2023 19:14:29 -0000 Received: (qmail 12182 invoked by uid 550); 4 May 2023 19:12:58 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 12087 invoked from network); 4 May 2023 19:12:57 -0000 Date: Thu, 4 May 2023 15:12:42 -0400 From: Rich Felker To: Markus Wichmann Cc: musl@lists.openwall.com Message-ID: <20230504191242.GG4163@brightrain.aerifal.cx> References: <20230504175208.GF4163@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230504175208.GF4163@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] Namespace violation in system()? On Thu, May 04, 2023 at 01:52:08PM -0400, Rich Felker wrote: > On Thu, May 04, 2023 at 06:33:27PM +0200, Markus Wichmann wrote: > > Hi all, > > > > I stumbled upon the source code of system() today. It is this at the > > moment: > > > > |int system(const char *cmd) > > |{ > > | pid_t pid; > > | sigset_t old, reset; > > | struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit; > > | int status = -1, ret; > > | posix_spawnattr_t attr; > > | > > | pthread_testcancel(); > > | > > | if (!cmd) return 1; > > | > > | sigaction(SIGINT, &sa, &oldint); > > | sigaction(SIGQUIT, &sa, &oldquit); > > | sigaddset(&sa.sa_mask, SIGCHLD); > > | sigprocmask(SIG_BLOCK, &sa.sa_mask, &old); > > | > > | sigemptyset(&reset); > > | if (oldint.sa_handler != SIG_IGN) sigaddset(&reset, SIGINT); > > | if (oldquit.sa_handler != SIG_IGN) sigaddset(&reset, SIGQUIT); > > | posix_spawnattr_init(&attr); > > | posix_spawnattr_setsigmask(&attr, &old); > > | posix_spawnattr_setsigdefault(&attr, &reset); > > | posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK); > > | ret = posix_spawn(&pid, "/bin/sh", 0, &attr, > > | (char *[]){"sh", "-c", (char *)cmd, 0}, __environ); > > | posix_spawnattr_destroy(&attr); > > | > > | if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR); > > | sigaction(SIGINT, &oldint, NULL); > > | sigaction(SIGQUIT, &oldquit, NULL); > > | sigprocmask(SIG_SETMASK, &old, NULL); > > | > > | if (ret) errno = ret; > > | return status; > > |} > > > > Aren't all of those calls namespace violations? system() is an ISO-C > > function, so the only symbols it is allowed to pull into the link are > > other ISO-C functions or hidden double-underscore symbols, right? But > > all the functions called here POSIX functions. And while POSIX contains > > the rule that posix_* functions are reserved, that is in POSIX, not > > ISO-C. And even with that rule, there are all the other calls. > > > > Does someone need to pour out a bucket of underscores over this > > function? > > The behavior of system() is implementation-defined, so we define it as > calling those functions. :-) To elaborate: "If string is a null pointer, the system function determines whether the host environment has a command processor. If string is not a null pointer, the system function passes the string pointed to by string to that command processor to be executed in a manner which the implementation shall document; this might then cause the program calling system to behave in a non-conforming manner or to terminate." The manner in which we pass the string to a command processor to be executed is via calls to external identifiers defined by POSIX. Even if this sounds like a silly way to be "technically conforming", it's really not. The semantics of calling system() are completely unspecified without assuming POSIX or some other specification beyond just plain C, so there's no reasonable way a C program running on top of the implementation can call system() without further assumptions about the implementation (e.g. that it's implementing POSIX). Rich