Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108229854
D38933.id118421.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D38933.id118421.diff
View Options
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -629,7 +629,7 @@
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
- SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_WANTABIPATH,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
@@ -643,6 +643,7 @@
.sv_ontdexit = linux_thread_dtor,
.sv_setid_allowed = &linux_setid_allowed_query,
.sv_set_fork_retval = linux_set_fork_retval,
+ .sv_alterlink = linux_alternate_link,
};
static int
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -854,7 +854,7 @@
.sv_fixlimit = linux32_fixlimit,
.sv_maxssiz = &linux32_maxssiz,
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_WANTABIPATH,
.sv_set_syscall_retval = linux32_set_syscall_retval,
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
.sv_syscallnames = linux32_syscallnames,
@@ -868,6 +868,7 @@
.sv_ontdexit = linux_thread_dtor,
.sv_setid_allowed = &linux_setid_allowed_query,
.sv_set_fork_retval = linux32_set_fork_retval,
+ .sv_alterlink = linux_alternate_link,
};
static int
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -431,7 +431,7 @@
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
- SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_WANTABIPATH,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
@@ -446,6 +446,7 @@
.sv_onexit = linux_on_exit,
.sv_ontdexit = linux_thread_dtor,
.sv_setid_allowed = &linux_setid_allowed_query,
+ .sv_alterlink = linux_alternate_link,
};
static int
diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h
--- a/sys/compat/linux/linux_util.h
+++ b/sys/compat/linux/linux_util.h
@@ -38,6 +38,8 @@
#include <sys/uio.h>
+struct nameidata;
+
MALLOC_DECLARE(M_LINUX);
MALLOC_DECLARE(M_EPOLL);
@@ -45,6 +47,7 @@
extern int linux_use_emul_path;
int linux_emul_convpath(const char *, enum uio_seg, char **, int, int);
+int linux_alternate_link(struct nameidata *, char *, int *);
#define LUSECONVPATH(td) atomic_load_int(&linux_use_emul_path)
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c
--- a/sys/compat/linux/linux_util.c
+++ b/sys/compat/linux/linux_util.c
@@ -96,6 +96,29 @@
return (retval);
}
+int
+linux_alternate_link(struct nameidata *ndp, char *cp, int *linklen)
+{
+ size_t len;
+ char *ncp;
+
+ if (!LUSECONVPATH(td))
+ return (0);
+ if (*linklen > 0 && cp[0] == '/') {
+ len = strlen(linux_emul_path);
+ if ((*linklen + len + 2) > MAXPATHLEN)
+ return (ENAMETOOLONG);
+ cp[*linklen] = '\0';
+ len = *linklen + len;
+ ncp = malloc(len, M_TEMP, M_WAITOK);
+ sprintf(ncp, "%s%s", linux_emul_path, cp);
+ bcopy(ncp, cp, len);
+ free(ncp, M_TEMP);
+ *linklen = len;
+ }
+ return (0);
+}
+
void
linux_msg(const struct thread *td, const char *fmt, ...)
{
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -655,6 +655,7 @@
.sv_ontdexit = linux_thread_dtor,
.sv_setid_allowed = &linux_setid_allowed_query,
.sv_set_fork_retval = linux_set_fork_retval,
+ .sv_alterlink = NULL,
};
INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
@@ -684,7 +685,7 @@
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_WANTABIPATH,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
@@ -698,6 +699,7 @@
.sv_ontdexit = linux_thread_dtor,
.sv_setid_allowed = &linux_setid_allowed_query,
.sv_set_fork_retval = linux_set_fork_retval,
+ .sv_alterlink = linux_alternate_link,
};
static int
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -791,6 +791,7 @@
struct nameidata *nd;
struct vattr *attr;
struct image_params *imgp;
+ uint64_t nd_flags;
u_long rbase;
u_long base_addr = 0;
int error;
@@ -815,11 +816,21 @@
imgp->proc = p;
imgp->attr = attr;
- NDINIT(nd, LOOKUP, ISOPEN | FOLLOW | LOCKSHARED | LOCKLEAF,
- UIO_SYSSPACE, file);
+ nd_flags = ISOPEN | FOLLOW | LOCKSHARED | LOCKLEAF;
+
+ NDINIT(nd, LOOKUP, nd_flags, UIO_SYSSPACE, file);
if ((error = namei(nd)) != 0) {
- nd->ni_vp = NULL;
- goto fail;
+ if (__predict_false(SV_PROC_FLAG(p, SV_WANTABIPATH) != 0)) {
+ nd_flags |= WANTABIPATH;
+ NDINIT_ABI(nd, LOOKUP, nd_flags, UIO_SYSSPACE, file, p);
+ if ((error = namei(nd)) != 0) {
+ nd->ni_vp = NULL;
+ goto fail;
+ }
+ } else {
+ nd->ni_vp = NULL;
+ goto fail;
+ }
}
NDFREE_PNBUF(nd);
imgp->vp = nd->ni_vp;
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -59,6 +59,7 @@
#include <sys/sdt.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -516,6 +517,18 @@
error = ENAMETOOLONG;
goto out;
}
+
+ /*
+ * Allow ABI to alter the link according to the ABI prefix.
+ */
+ if (__predict_false((cnp->cn_flags & WANTABIPATH) != 0)) {
+ error = (ndp->ni_sv->sv_alterlink)(ndp, cp, &linklen);
+ if (error != 0) {
+ if (ndp->ni_pathlen > 1)
+ uma_zfree(namei_zone, cp);
+ goto out;
+ }
+ }
if (ndp->ni_pathlen > 1) {
bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen);
uma_zfree(namei_zone, cnp->cn_pnbuf);
@@ -577,6 +590,15 @@
("%s: FAILIFEXISTS must be passed with LOCKPARENT and without LOCKLEAF",
__func__));
}
+ if ((cnp->cn_flags & WANTABIPATH) != 0) {
+ KASSERT(cnp->cn_nameiop == LOOKUP,
+ ("%s: WANTABIPATH passed for op %d", __func__, cnp->cn_nameiop));
+ KASSERT((cnp->cn_flags & FOLLOW) == FOLLOW,
+ ("%s: WANTABIPATH must be passed with FOLLOW",
+ __func__));
+ KASSERT(ndp->ni_sv != NULL,
+ ("%s: WANTABIPATH requires ni_sv", __func__));
+ }
#endif
ndp->ni_cnd.cn_cred = td->td_ucred;
KASSERT(ndp->ni_resflags == 0, ("%s: garbage in ni_resflags: %x\n",
@@ -1579,6 +1601,7 @@
{
struct nameidata nd, ndroot;
char *ptr, *buf, *cp;
+ struct proc *p;
size_t len, sz;
int error;
@@ -1629,18 +1652,19 @@
* and we want to create a file (cflag is set). We don't
* need to worry about the root comparison in this case.
*/
+ p = curproc;
if (create) {
for (cp = &ptr[len] - 1; *cp != '/'; cp--);
*cp = '\0';
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf);
+ NDINIT_ABI(&nd, LOOKUP, FOLLOW | WANTABIPATH, UIO_SYSSPACE, buf, p);
error = namei(&nd);
*cp = '/';
if (error != 0)
goto keeporig;
} else {
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf);
+ NDINIT_ABI(&nd, LOOKUP, FOLLOW | WANTABIPATH, UIO_SYSSPACE, buf, p);
error = namei(&nd);
if (error != 0)
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -111,6 +111,10 @@
*/
struct componentname ni_cnd;
struct nameicap_tracker_head ni_cap_tracker;
+ /*
+ * Private ABI info
+ */
+ struct sysentvec *ni_sv;
/*
* Private helper data for UFS, must be at the end. See
* NDINIT_PREFILL().
@@ -154,6 +158,7 @@
#define LOCKSHARED 0x0100 /* Shared lock leaf */
#define NOFOLLOW 0x0000 /* do not follow symbolic links (pseudo) */
#define RBENEATH 0x100000000ULL /* No escape, even tmp, from start dir */
+#define WANTABIPATH 0x200000000ULL /* Alternate ABI symlinks */
#define MODMASK 0xf000001ffULL /* mask of operational modifiers */
/*
@@ -207,13 +212,19 @@
* Initialization of a nameidata structure.
*/
#define NDINIT(ndp, op, flags, segflg, namep) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, &cap_no_rights)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, \
+ &cap_no_rights, NULL)
#define NDINIT_AT(ndp, op, flags, segflg, namep, dirfd) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, &cap_no_rights)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, \
+ &cap_no_rights, NULL)
#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rightsp) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp, NULL)
#define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, &cap_no_rights)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, \
+ &cap_no_rights, NULL)
+#define NDINIT_ABI(ndp, op, flags, segflg, namep, proc) \
+ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, \
+ &cap_no_rights, p->p_sysent)
/*
* Note the constant pattern may *hide* bugs.
@@ -238,7 +249,7 @@
#define NDREINIT_DBG(arg) do { } while (0)
#endif
-#define NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, startdir, rightsp) \
+#define NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, startdir, rightsp, sv) \
do { \
struct nameidata *_ndp = (ndp); \
cap_rights_t *_rightsp = (rightsp); \
@@ -252,6 +263,7 @@
_ndp->ni_dirfd = dirfd; \
_ndp->ni_startdir = startdir; \
_ndp->ni_resflags = 0; \
+ _ndp->ni_sv = sv; \
filecaps_init(&_ndp->ni_filecaps); \
_ndp->ni_rightsneeded = _rightsp; \
} while (0)
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -99,6 +99,7 @@
struct trapframe;
struct vnode;
struct note_info_list;
+struct nameidata;
struct sysentvec {
int sv_size; /* number of entries */
@@ -160,6 +161,7 @@
/* Only used on x86 */
struct regset **sv_regset_begin;
struct regset **sv_regset_end;
+ int (*sv_alterlink)(struct nameidata *, char *, int *);
};
#define SV_ILP32 0x000100 /* 32-bit executable. */
@@ -167,7 +169,7 @@
#define SV_IA32 0x004000 /* Intel 32-bit executable. */
#define SV_AOUT 0x008000 /* a.out executable. */
#define SV_SHP 0x010000 /* Shared page. */
-#define SV_AVAIL1 0x020000 /* Unused */
+#define SV_WANTABIPATH 0x020000 /* Requires sv_alterlink */
#define SV_TIMEKEEP 0x040000 /* Shared page timehands. */
#define SV_ASLR 0x080000 /* ASLR allowed. */
#define SV_RNG_SEED_VER 0x100000 /* random(4) reseed generation. */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 23, 9:35 PM (22 m, 25 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16064994
Default Alt Text
D38933.id118421.diff (10 KB)
Attached To
Mode
D38933: namei: Add the abilty for the ABI to specify an alternate root path
Attached
Detach File
Event Timeline
Log In to Comment