1*d91f98a8Spgoyette /* $NetBSD: compat_util.c,v 1.47 2019/01/27 02:08:39 pgoyette Exp $ */
28fb507a3Schristos
38fb507a3Schristos /*-
48fb507a3Schristos * Copyright (c) 1994 The NetBSD Foundation, Inc.
58fb507a3Schristos * All rights reserved.
68fb507a3Schristos *
78fb507a3Schristos * This code is derived from software contributed to The NetBSD Foundation
8192330fdSfvdl * by Christos Zoulas and Frank van der Linden.
98fb507a3Schristos *
108fb507a3Schristos * Redistribution and use in source and binary forms, with or without
118fb507a3Schristos * modification, are permitted provided that the following conditions
128fb507a3Schristos * are met:
138fb507a3Schristos * 1. Redistributions of source code must retain the above copyright
148fb507a3Schristos * notice, this list of conditions and the following disclaimer.
158fb507a3Schristos * 2. Redistributions in binary form must reproduce the above copyright
168fb507a3Schristos * notice, this list of conditions and the following disclaimer in the
178fb507a3Schristos * documentation and/or other materials provided with the distribution.
188fb507a3Schristos *
198fb507a3Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
208fb507a3Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
218fb507a3Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
228fb507a3Schristos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
238fb507a3Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
248fb507a3Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
258fb507a3Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
268fb507a3Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
278fb507a3Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
288fb507a3Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
298fb507a3Schristos * POSSIBILITY OF SUCH DAMAGE.
308fb507a3Schristos */
31dcb2a50bSchristos
3297c80e8fSmrg /*
3397c80e8fSmrg * Copyright (c) 2008, 2009 Matthew R. Green
3497c80e8fSmrg * All rights reserved.
3597c80e8fSmrg *
3697c80e8fSmrg * Redistribution and use in source and binary forms, with or without
3797c80e8fSmrg * modification, are permitted provided that the following conditions
3897c80e8fSmrg * are met:
3997c80e8fSmrg * 1. Redistributions of source code must retain the above copyright
4097c80e8fSmrg * notice, this list of conditions and the following disclaimer.
4197c80e8fSmrg * 2. Redistributions in binary form must reproduce the above copyright
4297c80e8fSmrg * notice, this list of conditions and the following disclaimer in the
4397c80e8fSmrg * documentation and/or other materials provided with the distribution.
4497c80e8fSmrg * 3. The name of the author may not be used to endorse or promote products
4597c80e8fSmrg * derived from this software without specific prior written permission.
4697c80e8fSmrg *
4797c80e8fSmrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
4897c80e8fSmrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
4997c80e8fSmrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5097c80e8fSmrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5197c80e8fSmrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
5297c80e8fSmrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5397c80e8fSmrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
5497c80e8fSmrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5597c80e8fSmrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5697c80e8fSmrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5797c80e8fSmrg * SUCH DAMAGE.
5897c80e8fSmrg */
5997c80e8fSmrg
60dab6ef8bSlukem #include <sys/cdefs.h>
61*d91f98a8Spgoyette __KERNEL_RCSID(0, "$NetBSD: compat_util.c,v 1.47 2019/01/27 02:08:39 pgoyette Exp $");
62*d91f98a8Spgoyette
63*d91f98a8Spgoyette #if defined(_KERNEL_OPT)
64*d91f98a8Spgoyette #include "opt_compat_netbsd.h"
65*d91f98a8Spgoyette #endif
66dab6ef8bSlukem
67dcb2a50bSchristos #include <sys/param.h>
68dcb2a50bSchristos #include <sys/systm.h>
69dcb2a50bSchristos #include <sys/namei.h>
70dcb2a50bSchristos #include <sys/proc.h>
71dcb2a50bSchristos #include <sys/file.h>
72dcb2a50bSchristos #include <sys/stat.h>
73dcb2a50bSchristos #include <sys/filedesc.h>
74bddeb302Sthorpej #include <sys/exec.h>
75dcb2a50bSchristos #include <sys/ioctl.h>
76dcb2a50bSchristos #include <sys/kernel.h>
77dcb2a50bSchristos #include <sys/vnode.h>
78811fbe17Sfvdl #include <sys/syslog.h>
79811fbe17Sfvdl #include <sys/mount.h>
80*d91f98a8Spgoyette #include <sys/module.h>
81dcb2a50bSchristos
82dcb2a50bSchristos #include <compat/common/compat_util.h>
83dcb2a50bSchristos
84302af6f0Sjdolecek /*
855b217baeScgd * Translate one set of flags to another, based on the entries in
865b217baeScgd * the given table. If 'leftover' is specified, it is filled in
875b217baeScgd * with any flags which could not be translated.
885b217baeScgd */
895b217baeScgd unsigned long
emul_flags_translate(const struct emul_flags_xtab * tab,unsigned long in,unsigned long * leftover)905b217baeScgd emul_flags_translate(const struct emul_flags_xtab *tab,
915b217baeScgd unsigned long in, unsigned long *leftover)
925b217baeScgd {
935b217baeScgd unsigned long out;
945b217baeScgd
955b217baeScgd for (out = 0; tab->omask != 0; tab++) {
965b217baeScgd if ((in & tab->omask) == tab->oval) {
975b217baeScgd in &= ~tab->omask;
985b217baeScgd out |= tab->nval;
995b217baeScgd }
1005b217baeScgd }
1015b217baeScgd if (leftover != NULL)
1025b217baeScgd *leftover = in;
1035b217baeScgd return (out);
1045b217baeScgd }
1055b217baeScgd
106811fbe17Sfvdl void
compat_offseterr(struct vnode * vp,const char * msg)10728bae79bSdsl compat_offseterr(struct vnode *vp, const char *msg)
108811fbe17Sfvdl {
109811fbe17Sfvdl struct mount *mp;
110811fbe17Sfvdl
111811fbe17Sfvdl mp = vp->v_mount;
112811fbe17Sfvdl
113811fbe17Sfvdl log(LOG_ERR, "%s: dir offset too large on fs %s (mounted from %s)\n",
114811fbe17Sfvdl msg, mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname);
115811fbe17Sfvdl uprintf("%s: dir offset too large for emulated program\n", msg);
116811fbe17Sfvdl }
11797c80e8fSmrg
11897c80e8fSmrg /*
11997c80e8fSmrg * Look for native NetBSD compatibility libraries, usually interp-ABI.
12097c80e8fSmrg * It returns 0 if it changed the interpreter, otherwise it returns
12197c80e8fSmrg * the error from namei(). Callers should not try any more processing
12297c80e8fSmrg * if this returns 0, and probably should just ignore the return value.
12397c80e8fSmrg */
12497c80e8fSmrg int
compat_elf_check_interp(struct exec_package * epp,char * interp,const char * interp_suffix)12597c80e8fSmrg compat_elf_check_interp(struct exec_package *epp,
12697c80e8fSmrg char *interp,
12797c80e8fSmrg const char *interp_suffix)
12897c80e8fSmrg {
12997c80e8fSmrg int error = 0;
13097c80e8fSmrg
13197c80e8fSmrg /*
13297c80e8fSmrg * Don't look for something else, if someone has already found and
13397c80e8fSmrg * setup the ep_interp already.
13497c80e8fSmrg */
13597c80e8fSmrg if (interp && epp->ep_interp == NULL) {
13697c80e8fSmrg /*
13797c80e8fSmrg * If the path is exactly "/usr/libexec/ld.elf_so", first
13897c80e8fSmrg * try to see if "/usr/libexec/ld.elf_so-<abi>" exists
13997c80e8fSmrg * and if so, use that instead.
14097c80e8fSmrg */
14197c80e8fSmrg if (strcmp(interp, "/usr/libexec/ld.elf_so") == 0 ||
14297c80e8fSmrg strcmp(interp, "/libexec/ld.elf_so") == 0) {
14397c80e8fSmrg struct vnode *vp;
14497c80e8fSmrg char *path;
14597c80e8fSmrg
14697c80e8fSmrg path = PNBUF_GET();
14797c80e8fSmrg snprintf(path, MAXPATHLEN, "%s-%s", interp, interp_suffix);
14897c80e8fSmrg error = namei_simple_kernel(path,
14997c80e8fSmrg NSM_FOLLOW_NOEMULROOT, &vp);
15097c80e8fSmrg /*
15197c80e8fSmrg * If that worked, replace interpreter in case we
15297c80e8fSmrg * actually need to load it.
15397c80e8fSmrg */
15497c80e8fSmrg if (error == 0) {
15597c80e8fSmrg epp->ep_interp = vp;
15697c80e8fSmrg snprintf(interp, MAXPATHLEN, "%s", path);
15797c80e8fSmrg }
15897c80e8fSmrg PNBUF_PUT(path);
15997c80e8fSmrg }
16097c80e8fSmrg }
16197c80e8fSmrg return error;
16297c80e8fSmrg }
163*d91f98a8Spgoyette
164*d91f98a8Spgoyette MODULE(MODULE_CLASS_MISC, compat_util, NULL);
165*d91f98a8Spgoyette
166*d91f98a8Spgoyette int
compat_util_modcmd(modcmd_t cmd,void * arg)167*d91f98a8Spgoyette compat_util_modcmd(modcmd_t cmd, void *arg)
168*d91f98a8Spgoyette {
169*d91f98a8Spgoyette
170*d91f98a8Spgoyette switch (cmd) {
171*d91f98a8Spgoyette case MODULE_CMD_INIT:
172*d91f98a8Spgoyette case MODULE_CMD_FINI:
173*d91f98a8Spgoyette return 0;
174*d91f98a8Spgoyette default:
175*d91f98a8Spgoyette return ENOTTY;
176*d91f98a8Spgoyette }
177*d91f98a8Spgoyette }
178