1 /* $NetBSD: linux32_uid16.c,v 1.1 2008/01/15 22:38:35 njoly Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 * Copyright (c) 2008 Nicolas Joly, all rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Emmanuel Dreyfus 18 * 4. The name of the author may not be used to endorse or promote 19 * products derived from this software without specific prior written 20 * permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: linux32_uid16.c,v 1.1 2008/01/15 22:38:35 njoly Exp $"); 37 38 #include <sys/param.h> 39 #include <sys/proc.h> 40 #include <sys/kauth.h> 41 42 #include <compat/netbsd32/netbsd32.h> 43 44 #include <compat/linux/common/linux_types.h> 45 #include <compat/linux/common/linux_signal.h> 46 #include <compat/linux/linux_syscallargs.h> 47 48 #include <compat/linux32/common/linux32_types.h> 49 #include <compat/linux32/common/linux32_signal.h> 50 #include <compat/linux32/common/linux32_machdep.h> 51 #include <compat/linux32/linux32_syscallargs.h> 52 53 #define LINUX32TOBSD_UID(u) \ 54 (((u) == (linux32_uid16_t)-1) ? -1 : (u)) 55 #define LINUX32TOBSD_GID(g) \ 56 (((g) == (linux32_gid16_t)-1) ? -1 : (g)) 57 58 #define BSDTOLINUX32_UID(u) \ 59 (((u) & ~0xffff) ? (linux32_uid16_t)65534 : (linux32_uid16_t)(u)) 60 #define BSDTOLINUX32_GID(g) \ 61 (((g) & ~0xffff) ? (linux32_gid16_t)65534 : (linux32_gid16_t)(g)) 62 63 int 64 linux32_sys_chown16(struct lwp *l, const struct linux32_sys_chown16_args *uap, register_t *retval) 65 { 66 /* { 67 syscallarg(const netbsd32_charp) path; 68 syscallarg(linux32_uid16_t) uid; 69 syscallarg(linux32_gid16_t) gid; 70 } */ 71 struct sys___posix_chown_args ua; 72 73 NETBSD32TOP_UAP(path, const char); 74 SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid)); 75 SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid)); 76 77 return sys___posix_chown(l, &ua, retval); 78 } 79 80 int 81 linux32_sys_lchown16(struct lwp *l, const struct linux32_sys_lchown16_args *uap, register_t *retval) 82 { 83 /* { 84 syscallarg(const netbsd32_charp) path; 85 syscallarg(linux32_uid16_t) uid; 86 syscallarg(linux32_gid16_t) gid; 87 } */ 88 struct sys___posix_lchown_args ua; 89 90 NETBSD32TOP_UAP(path, const char); 91 SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid)); 92 SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid)); 93 94 return sys___posix_lchown(l, &ua, retval); 95 } 96 97 int 98 linux32_sys_fchown16(struct lwp *l, const struct linux32_sys_fchown16_args *uap, register_t *retval) 99 { 100 /* { 101 syscallarg(int) fd; 102 syscallarg(linux32_uid16_t) uid; 103 syscallarg(linux32_gid16_t) gid; 104 } */ 105 struct sys___posix_fchown_args ua; 106 107 SCARG(&ua, fd) = SCARG(uap, fd); 108 SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid)); 109 SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid)); 110 111 return sys___posix_fchown(l, &ua, retval); 112 } 113 114 int 115 linux32_sys_getgroups16(struct lwp *l, const struct linux32_sys_getgroups16_args *uap, register_t *retval) 116 { 117 /* { 118 syscallarg(int) gidsetsize; 119 syscallarg(linux32_gid16p_t) gidset; 120 } */ 121 struct linux_sys_getgroups16_args ua; 122 123 NETBSD32TO64_UAP(gidsetsize); 124 NETBSD32TOP_UAP(gidset, linux_gid16_t); 125 126 return linux_sys_getgroups16(l, &ua, retval); 127 } 128 129 int 130 linux32_sys_setgroups16(struct lwp *l, const struct linux32_sys_setgroups16_args *uap, register_t *retval) 131 { 132 /* { 133 syscallarg(int) gidsetsize; 134 syscallarg(linux32_gid16p_t) gidset; 135 } */ 136 struct linux_sys_setgroups16_args ua; 137 138 NETBSD32TO64_UAP(gidsetsize); 139 NETBSD32TOP_UAP(gidset, linux_gid16_t); 140 141 return linux_sys_setgroups16(l, &ua, retval); 142 } 143 144 int 145 linux32_sys_setreuid16(struct lwp *l, const struct linux32_sys_setreuid16_args *uap, register_t *retval) 146 { 147 /* { 148 syscallarg(linux32_uid16_t) ruid; 149 syscallarg(linux32_uid16_t) euid; 150 } */ 151 struct sys_setreuid_args bsa; 152 153 SCARG(&bsa, ruid) = LINUX32TOBSD_UID(SCARG(uap, ruid)); 154 SCARG(&bsa, euid) = LINUX32TOBSD_UID(SCARG(uap, euid)); 155 156 return sys_setreuid(l, &bsa, retval); 157 } 158 159 int 160 linux32_sys_setregid16(struct lwp *l, const struct linux32_sys_setregid16_args *uap, register_t *retval) 161 { 162 /* { 163 syscallarg(linux32_gid16_t) rgid; 164 syscallarg(linux32_gid16_t) egid; 165 } */ 166 struct sys_setregid_args bsa; 167 168 SCARG(&bsa, rgid) = LINUX32TOBSD_GID(SCARG(uap, rgid)); 169 SCARG(&bsa, egid) = LINUX32TOBSD_GID(SCARG(uap, egid)); 170 171 return sys_setregid(l, &bsa, retval); 172 } 173 174 int 175 linux32_sys_setresuid16(struct lwp *l, const struct linux32_sys_setresuid16_args *uap, register_t *retval) 176 { 177 /* { 178 syscallarg(linux32_uid16_t) ruid; 179 syscallarg(linux32_uid16_t) euid; 180 syscallarg(linux32_uid16_t) suid; 181 } */ 182 struct linux32_sys_setresuid_args lsa; 183 184 SCARG(&lsa, ruid) = LINUX32TOBSD_UID(SCARG(uap, ruid)); 185 SCARG(&lsa, euid) = LINUX32TOBSD_UID(SCARG(uap, euid)); 186 SCARG(&lsa, suid) = LINUX32TOBSD_UID(SCARG(uap, suid)); 187 188 return linux32_sys_setresuid(l, &lsa, retval); 189 } 190 191 int 192 linux32_sys_setresgid16(struct lwp *l, const struct linux32_sys_setresgid16_args *uap, register_t *retval) 193 { 194 /* { 195 syscallarg(linux32_gid16_t) rgid; 196 syscallarg(linux32_gid16_t) egid; 197 syscallarg(linux32_gid16_t) sgid; 198 } */ 199 struct linux32_sys_setresgid_args lsa; 200 201 SCARG(&lsa, rgid) = LINUX32TOBSD_GID(SCARG(uap, rgid)); 202 SCARG(&lsa, egid) = LINUX32TOBSD_GID(SCARG(uap, egid)); 203 SCARG(&lsa, sgid) = LINUX32TOBSD_GID(SCARG(uap, sgid)); 204 205 return linux32_sys_setresgid(l, &lsa, retval); 206 } 207 208 int 209 linux32_sys_getresuid16(struct lwp *l, const struct linux32_sys_getresuid16_args *uap, register_t *retval) 210 { 211 /* { 212 syscallarg(linux32_uid16p_t) ruid; 213 syscallarg(linux32_uid16p_t) euid; 214 syscallarg(linux32_uid16p_t) suid; 215 } */ 216 kauth_cred_t pc = l->l_cred; 217 int error; 218 uid_t buid; 219 linux32_uid16_t luid; 220 221 buid = kauth_cred_getuid(pc); 222 luid = BSDTOLINUX32_UID(buid); 223 if ((error = copyout(&luid, SCARG_P32(uap, ruid), sizeof(luid))) != 0) 224 return error; 225 226 buid = kauth_cred_geteuid(pc); 227 luid = BSDTOLINUX32_UID(buid); 228 if ((error = copyout(&luid, SCARG_P32(uap, euid), sizeof(luid))) != 0) 229 return error; 230 231 buid = kauth_cred_getsvuid(pc); 232 luid = BSDTOLINUX32_UID(buid); 233 return (copyout(&luid, SCARG_P32(uap, suid), sizeof(luid))); 234 } 235 236 int 237 linux32_sys_getresgid16(struct lwp *l, const struct linux32_sys_getresgid16_args *uap, register_t *retval) 238 { 239 /* { 240 syscallarg(linux32_gid16p_t) rgid; 241 syscallarg(linux32_gid16p_t) egid; 242 syscallarg(linux32_gid16p_t) sgid; 243 } */ 244 kauth_cred_t pc = l->l_cred; 245 int error; 246 gid_t bgid; 247 linux32_gid16_t lgid; 248 249 bgid = kauth_cred_getgid(pc); 250 lgid = BSDTOLINUX32_GID(bgid); 251 if ((error = copyout(&lgid, SCARG_P32(uap, rgid), sizeof(lgid))) != 0) 252 return error; 253 254 bgid = kauth_cred_getegid(pc); 255 lgid = BSDTOLINUX32_GID(bgid); 256 if ((error = copyout(&lgid, SCARG_P32(uap, egid), sizeof(lgid))) != 0) 257 return error; 258 259 bgid = kauth_cred_getsvgid(pc); 260 lgid = BSDTOLINUX32_GID(bgid); 261 return (copyout(&lgid, SCARG_P32(uap, sgid), sizeof(lgid))); 262 } 263