Page MenuHomeFreeBSD

D25501.1788247876.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D25501.1788247876.diff

Index: sys/compat/linux/linux_emul.c
===================================================================
--- sys/compat/linux/linux_emul.c
+++ sys/compat/linux/linux_emul.c
@@ -316,6 +316,7 @@
/*
* We are switching the process to Linux emulator.
*/
+ linux_xchroot(td);
linux_proc_init(td, td, 0);
/*
Index: sys/compat/linux/linux_mib.h
===================================================================
--- sys/compat/linux/linux_mib.h
+++ sys/compat/linux/linux_mib.h
@@ -67,5 +67,6 @@
extern int linux_ignore_ip_recverr;
extern int linux_preserve_vstatus;
extern bool linux_map_sched_prio;
+extern bool linux_autochroot;
#endif /* _LINUX_MIB_H_ */
Index: sys/compat/linux/linux_mib.c
===================================================================
--- sys/compat/linux/linux_mib.c
+++ sys/compat/linux/linux_mib.c
@@ -85,6 +85,10 @@
&linux_map_sched_prio, 0, "Map scheduler priorities to Linux priorities "
"(not POSIX compliant)");
+bool linux_autochroot = false;
+SYSCTL_BOOL(_compat_linux, OID_AUTO, autochroot, CTLFLAG_RWTUN,
+ &linux_autochroot, 0, "XXX");
+
static int linux_set_osname(struct thread *td, char *osname);
static int linux_set_osrelease(struct thread *td, char *osrelease);
static int linux_set_oss_version(struct thread *td, int oss_version);
Index: sys/compat/linux/linux_util.h
===================================================================
--- sys/compat/linux/linux_util.h
+++ sys/compat/linux/linux_util.h
@@ -122,6 +122,7 @@
int linux_driver_get_major_minor(const char *node, int *major, int *minor);
char *linux_get_char_devices(void);
void linux_free_get_char_devices(char *string);
+int linux_xchroot(struct thread *td);
#if defined(KTR)
Index: sys/compat/linux/linux_util.c
===================================================================
--- sys/compat/linux/linux_util.c
+++ sys/compat/linux/linux_util.c
@@ -66,6 +66,49 @@
linux_emul_path, sizeof(linux_emul_path),
"Linux runtime environment path");
+int
+linux_xchroot(struct thread *td)
+{
+ struct nameidata nd;
+ int error;
+
+ if (!linux_autochroot)
+ return (0);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
+ UIO_SYSSPACE, "/compat/ubuntu", td);
+ error = namei(&nd);
+ if (error != 0) {
+ printf("%s: namei returned %d\n", __func__, error);
+ goto error;
+ }
+ error = change_dir(nd.ni_vp, td);
+ if (error != 0) {
+ printf("%s: change_dir returned %d\n", __func__, error);
+ goto e_vunlock;
+ }
+#if 0
+#ifdef MAC
+ error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp);
+ if (error != 0) {
+ printf("%s: mac_vnode_check_chroot returned %d\n", __func__, error);
+ goto e_vunlock;
+ }
+#endif
+#endif
+ VOP_UNLOCK(nd.ni_vp);
+ error = pwd_xchroot(td, nd.ni_vp);
+ vrele(nd.ni_vp);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ return (0);
+e_vunlock:
+ vput(nd.ni_vp);
+error:
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ return (0);
+}
+
+
/*
* Search an alternate path before passing pathname arguments on to
* system calls. Useful for keeping a separate 'emulation tree'.
@@ -77,7 +120,27 @@
linux_emul_convpath(struct thread *td, const char *path, enum uio_seg pathseg,
char **pbuf, int cflag, int dfd)
{
- int retval;
+ char *buf;
+ int error, retval;
+
+ if (linux_autochroot) {
+ buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+
+ /* Append the filename to the prefix. */
+ if (pathseg == UIO_SYSSPACE)
+ error = copystr(path, buf, MAXPATHLEN, NULL);
+ else
+ error = copyinstr(path, buf, MAXPATHLEN, NULL);
+
+ if (error != 0) {
+ free(buf, M_TEMP);
+ *pbuf = NULL;
+ } else {
+ *pbuf = buf;
+ }
+
+ return (error);
+ }
retval = kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
cflag, dfd);
Index: sys/kern/kern_descrip.c
===================================================================
--- sys/kern/kern_descrip.c
+++ sys/kern/kern_descrip.c
@@ -3424,6 +3424,37 @@
return (0);
}
+int
+pwd_xchroot(struct thread *td, struct vnode *vp)
+{
+ struct filedesc *fdp;
+ struct pwd *newpwd, *oldpwd;
+
+ fdp = td->td_proc->p_fd;
+ newpwd = pwd_alloc();
+ FILEDESC_XLOCK(fdp);
+ oldpwd = FILEDESC_XLOCKED_LOAD_PWD(fdp);
+ if (oldpwd->pwd_jdir != NULL ||
+ oldpwd->pwd_rdir != rootvnode) {
+ printf("%s: jailed or chrooted\n", __func__);
+ FILEDESC_XUNLOCK(fdp);
+ pwd_drop(newpwd);
+ return (EBUSY);
+ }
+
+ vrefact(vp);
+ newpwd->pwd_rdir = vp;
+ if (oldpwd->pwd_jdir == NULL) {
+ vrefact(vp);
+ newpwd->pwd_jdir = vp;
+ }
+ pwd_fill(oldpwd, newpwd);
+ pwd_set(fdp, newpwd);
+ FILEDESC_XUNLOCK(fdp);
+ pwd_drop(oldpwd);
+ return (0);
+}
+
void
pwd_chdir(struct thread *td, struct vnode *vp)
{
Index: sys/sys/filedesc.h
===================================================================
--- sys/sys/filedesc.h
+++ sys/sys/filedesc.h
@@ -297,6 +297,7 @@
/* cdir/rdir/jdir manipulation functions. */
void pwd_chdir(struct thread *td, struct vnode *vp);
int pwd_chroot(struct thread *td, struct vnode *vp);
+int pwd_xchroot(struct thread *td, struct vnode *vp);
void pwd_ensure_dirs(void);
void pwd_set_rootvnode(void);

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 1, 7:31 AM (8 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29496206
Default Alt Text
D25501.1788247876.diff (4 KB)

Event Timeline