Print this page
5798 fexecve() needed per POSIX 2008
@@ -18,10 +18,11 @@
*
* CDDL HEADER END
*/
/*
+ * Copyright 2015 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
@@ -96,10 +97,12 @@
uint_t auxv_hwcap32_2 = 0; /* 32-bit version of auxv_hwcap2 */
#endif
#define PSUIDFLAGS (SNOCD|SUGID)
+#define DEVFD "/dev/fd/"
+
/*
* exece() - system call wrapper around exec_common()
*/
int
exece(const char *fname, const char **argp, const char **envp)
@@ -196,11 +199,26 @@
* there are other cases in which that failure may occur.
*/
if ((error = pn_get((char *)fname, UIO_USERSPACE, &pn)) != 0)
goto out;
pn_alloc(&resolvepn);
- if ((error = lookuppn(&pn, &resolvepn, FOLLOW, &dir, &vp)) != 0) {
+
+ if (strncmp(pn.pn_path, DEVFD, strlen(DEVFD)) == 0) {
+ /* looks like a /dev/fd node */
+ char *p = pn.pn_path + strlen(DEVFD);
+ int fd = stoi(&p);
+ if ((fd < 0) || (*p != 0) || (p == pn.pn_path)) {
+ error = EBADF;
+ goto out;
+ }
+ if ((error = fgetstartvp(fd, NULL, &vp)) != 0) {
+ goto out; /* error will be EBADF */
+ }
+ (void) pn_set(&resolvepn, pn.pn_path);
+
+ } else if ((error =
+ lookuppn(&pn, &resolvepn, FOLLOW, &dir, &vp)) != 0) {
pn_free(&resolvepn);
pn_free(&pn);
if (error != EINVAL)
goto out;