ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/usr.sbin/jail/command.c
(Generate patch)

Comparing trunk/usr.sbin/jail/command.c (file contents):
Revision 10735 by laffer1, Fri Sep 30 01:55:48 2016 UTC vs.
Revision 10736 by laffer1, Sat Jun 9 22:07:11 2018 UTC

# Line 1 | Line 1
1 + /* $MidnightBSD$ */
2   /*-
3   * Copyright (c) 2011 James Gritton
4   * All rights reserved.
# Line 25 | Line 26
26   */
27  
28   #include <sys/cdefs.h>
29 < __MBSDID("$MidnightBSD$");
29 > __FBSDID("$FreeBSD: stable/10/usr.sbin/jail/command.c 302958 2016-07-17 14:15:08Z jamie $");
30  
31   #include <sys/types.h>
32   #include <sys/event.h>
# Line 47 | Line 48 | __MBSDID("$MidnightBSD$");
48   #include <stdlib.h>
49   #include <string.h>
50   #include <unistd.h>
51 + #include <vis.h>
52  
53   #include "jailp.h"
54  
# Line 91 | Line 93 | next_command(struct cfjail *j)
93          int create_failed, stopping;
94  
95          if (paralimit == 0) {
96 <                requeue(j, &runnable);
96 >                if (j->flags & JF_FROM_RUNQ)
97 >                        requeue_head(j, &runnable);
98 >                else
99 >                        requeue(j, &runnable);
100                  return 1;
101          }
102 +        j->flags &= ~JF_FROM_RUNQ;
103          create_failed = (j->flags & (JF_STOP | JF_FAILED)) == JF_FAILED;
104          stopping = (j->flags & JF_STOP) != 0;
105          comparam = *j->comparam;
# Line 106 | Line 112 | next_command(struct cfjail *j)
112                          case IP_MOUNT_DEVFS:
113                                  if (!bool_param(j->intparams[IP_MOUNT_DEVFS]))
114                                          continue;
115 <                                /* FALLTHROUGH */
115 >                                j->comstring = &dummystring;
116 >                                break;
117 >                        case IP_MOUNT_FDESCFS:
118 >                                if (!bool_param(j->intparams[IP_MOUNT_FDESCFS]))
119 >                                        continue;
120 >                                j->comstring = &dummystring;
121 >                                break;
122 >                        case IP_MOUNT_PROCFS:
123 >                                if (!bool_param(j->intparams[IP_MOUNT_PROCFS]))
124 >                                        continue;
125 >                                j->comstring = &dummystring;
126 >                                break;
127                          case IP__OP:
128                          case IP_STOP_TIMEOUT:
129                                  j->comstring = &dummystring;
# Line 148 | Line 165 | next_command(struct cfjail *j)
165   int
166   finish_command(struct cfjail *j)
167   {
168 +        struct cfjail *rj;
169          int error;
170  
171          if (!(j->flags & JF_SLEEPQ))
172                  return 0;
173          j->flags &= ~JF_SLEEPQ;
174 <        if (*j->comparam == IP_STOP_TIMEOUT)
157 <        {
174 >        if (*j->comparam == IP_STOP_TIMEOUT) {
175                  j->flags &= ~JF_TIMEOUT;
176                  j->pstatus = 0;
177                  return 0;
178          }
179          paralimit++;
180 <        if (!TAILQ_EMPTY(&runnable))
181 <                requeue(TAILQ_FIRST(&runnable), &ready);
180 >        if (!TAILQ_EMPTY(&runnable)) {
181 >                rj = TAILQ_FIRST(&runnable);
182 >                rj->flags |= JF_FROM_RUNQ;
183 >                requeue(rj, &ready);
184 >        }
185          error = 0;
186          if (j->flags & JF_TIMEOUT) {
187                  j->flags &= ~JF_TIMEOUT;
# Line 247 | Line 267 | next_proc(int nonblock)
267   }
268  
269   /*
270 < * Run a single command for a jail, possible inside the jail.
270 > * Run a single command for a jail, possibly inside the jail.
271   */
272   static int
273   run_command(struct cfjail *j)
# Line 263 | Line 283 | run_command(struct cfjail *j)
283          pid_t pid;
284          int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout;
285   #if defined(INET) || defined(INET6)
286 <        char *addr;
286 >        char *addr, *extrap, *p, *val;
287   #endif
288  
289          static char *cleanenv;
# Line 312 | Line 332 | run_command(struct cfjail *j)
332          switch (comparam) {
333   #ifdef INET
334          case IP__IP4_IFADDR:
335 <                argv = alloca(8 * sizeof(char *));
335 >                argc = 0;
336 >                val = alloca(strlen(comstring->s) + 1);
337 >                strcpy(val, comstring->s);
338 >                cs = val;
339 >                extrap = NULL;
340 >                while ((p = strchr(cs, ' ')) != NULL && strlen(p) > 1) {
341 >                        if (extrap == NULL) {
342 >                                *p = '\0';
343 >                                extrap = p + 1;
344 >                        }
345 >                        cs = p + 1;
346 >                        argc++;
347 >                }
348 >
349 >                argv = alloca((8 + argc) * sizeof(char *));
350                  *(const char **)&argv[0] = _PATH_IFCONFIG;
351 <                if ((cs = strchr(comstring->s, '|'))) {
352 <                        argv[1] = alloca(cs - comstring->s + 1);
353 <                        strlcpy(argv[1], comstring->s, cs - comstring->s + 1);
351 >                if ((cs = strchr(val, '|'))) {
352 >                        argv[1] = alloca(cs - val + 1);
353 >                        strlcpy(argv[1], val, cs - val + 1);
354                          addr = cs + 1;
355                  } else {
356                          *(const char **)&argv[1] =
357                              string_param(j->intparams[IP_INTERFACE]);
358 <                        addr = comstring->s;
358 >                        addr = val;
359                  }
360                  *(const char **)&argv[2] = "inet";
361                  if (!(cs = strchr(addr, '/'))) {
# Line 339 | Line 373 | run_command(struct cfjail *j)
373                          argv[3] = addr;
374                          argc = 4;
375                  }
376 +
377 +                if (!down) {
378 +                        for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) {
379 +                                size_t len = strlen(cs) + 1;
380 +                                argv[argc] = alloca(len);
381 +                                strlcpy(argv[argc++], cs, len);
382 +                        }
383 +                }
384 +
385                  *(const char **)&argv[argc] = down ? "-alias" : "alias";
386                  argv[argc + 1] = NULL;
387                  break;
# Line 346 | Line 389 | run_command(struct cfjail *j)
389  
390   #ifdef INET6
391          case IP__IP6_IFADDR:
392 <                argv = alloca(8 * sizeof(char *));
392 >                argc = 0;
393 >                val = alloca(strlen(comstring->s) + 1);
394 >                strcpy(val, comstring->s);
395 >                cs = val;
396 >                extrap = NULL;
397 >                while ((p = strchr(cs, ' ')) != NULL && strlen(p) > 1) {
398 >                        if (extrap == NULL) {
399 >                                *p = '\0';
400 >                                extrap = p + 1;
401 >                        }
402 >                        cs = p + 1;
403 >                        argc++;
404 >                }
405 >
406 >                argv = alloca((8 + argc) * sizeof(char *));
407                  *(const char **)&argv[0] = _PATH_IFCONFIG;
408 <                if ((cs = strchr(comstring->s, '|'))) {
409 <                        argv[1] = alloca(cs - comstring->s + 1);
410 <                        strlcpy(argv[1], comstring->s, cs - comstring->s + 1);
408 >                if ((cs = strchr(val, '|'))) {
409 >                        argv[1] = alloca(cs - val + 1);
410 >                        strlcpy(argv[1], val, cs - val + 1);
411                          addr = cs + 1;
412                  } else {
413                          *(const char **)&argv[1] =
414                              string_param(j->intparams[IP_INTERFACE]);
415 <                        addr = comstring->s;
415 >                        addr = val;
416                  }
417                  *(const char **)&argv[2] = "inet6";
418                  argv[3] = addr;
# Line 365 | Line 422 | run_command(struct cfjail *j)
422                          argc = 6;
423                  } else
424                          argc = 4;
425 +
426 +                if (!down) {
427 +                        for (cs = strtok(extrap, " "); cs; cs = strtok(NULL, " ")) {
428 +                                size_t len = strlen(cs) + 1;
429 +                                argv[argc] = alloca(len);
430 +                                strlcpy(argv[argc++], cs, len);
431 +                        }
432 +                }
433 +
434                  *(const char **)&argv[argc] = down ? "-alias" : "alias";
435                  argv[argc + 1] = NULL;
436                  break;  
# Line 388 | Line 454 | run_command(struct cfjail *j)
454                  strcpy(comcs, comstring->s);
455                  argc = 0;
456                  for (cs = strtok(comcs, " \t\f\v\r\n"); cs && argc < 4;
457 <                     cs = strtok(NULL, " \t\f\v\r\n"))
457 >                     cs = strtok(NULL, " \t\f\v\r\n")) {
458 >                        if (argc <= 1 && strunvis(cs, cs) < 0) {
459 >                                jail_warnx(j, "%s: %s: fstab parse error",
460 >                                    j->intparams[comparam]->name, comstring->s);
461 >                                return -1;
462 >                        }
463                          argv[argc++] = cs;
464 +                }
465                  if (argc == 0)
466                          return 0;
467                  if (argc < 3) {
# Line 452 | Line 524 | run_command(struct cfjail *j)
524                  }
525                  break;
526  
527 +        case IP_MOUNT_FDESCFS:
528 +                argv = alloca(7 * sizeof(char *));
529 +                path = string_param(j->intparams[KP_PATH]);
530 +                if (path == NULL) {
531 +                        jail_warnx(j, "mount.fdescfs: no path");
532 +                        return -1;
533 +                }
534 +                devpath = alloca(strlen(path) + 8);
535 +                sprintf(devpath, "%s/dev/fd", path);
536 +                if (check_path(j, "mount.fdescfs", devpath, 0,
537 +                    down ? "fdescfs" : NULL) < 0)
538 +                        return -1;
539 +                if (down) {
540 +                        *(const char **)&argv[0] = "/sbin/umount";
541 +                        argv[1] = devpath;
542 +                        argv[2] = NULL;
543 +                } else {
544 +                        *(const char **)&argv[0] = _PATH_MOUNT;
545 +                        *(const char **)&argv[1] = "-t";
546 +                        *(const char **)&argv[2] = "fdescfs";
547 +                        *(const char **)&argv[3] = ".";
548 +                        argv[4] = devpath;
549 +                        argv[5] = NULL;
550 +                }
551 +                break;
552 +
553 +        case IP_MOUNT_PROCFS:
554 +                argv = alloca(7 * sizeof(char *));
555 +                path = string_param(j->intparams[KP_PATH]);
556 +                if (path == NULL) {
557 +                        jail_warnx(j, "mount.procfs: no path");
558 +                        return -1;
559 +                }
560 +                devpath = alloca(strlen(path) + 6);
561 +                sprintf(devpath, "%s/proc", path);
562 +                if (check_path(j, "mount.procfs", devpath, 0,
563 +                    down ? "procfs" : NULL) < 0)
564 +                        return -1;
565 +                if (down) {
566 +                        *(const char **)&argv[0] = "/sbin/umount";
567 +                        argv[1] = devpath;
568 +                        argv[2] = NULL;
569 +                } else {
570 +                        *(const char **)&argv[0] = _PATH_MOUNT;
571 +                        *(const char **)&argv[1] = "-t";
572 +                        *(const char **)&argv[2] = "procfs";
573 +                        *(const char **)&argv[3] = ".";
574 +                        argv[4] = devpath;
575 +                        argv[5] = NULL;
576 +                }
577 +                break;
578 +
579          case IP_COMMAND:
580                  if (j->name != NULL)
581                          goto default_command;
# Line 591 | Line 715 | run_command(struct cfjail *j)
715                          if (term != NULL)
716                                  setenv("TERM", term, 1);
717                  }
718 +                if (setgid(pwd->pw_gid) < 0) {
719 +                        jail_warnx(j, "setgid %d: %s", pwd->pw_gid,
720 +                            strerror(errno));
721 +                        exit(1);
722 +                }
723                  if (setusercontext(lcap, pwd, pwd->pw_uid, username
724                      ? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN
725                      : LOGIN_SETPATH | LOGIN_SETENV) < 0) {
# Line 648 | Line 777 | add_proc(struct cfjail *j, pid_t pid)
777          if (j->timeout.tv_sec == 0)
778                  requeue(j, &sleeping);
779          else {
780 <                /* File the jail in the sleep queue acording to its timeout. */
780 >                /* File the jail in the sleep queue according to its timeout. */
781                  TAILQ_REMOVE(j->queue, j, tq);
782                  TAILQ_FOREACH(tj, &sleeping, tq) {
783                          if (!tj->timeout.tv_sec ||
# Line 764 | Line 893 | get_user_info(struct cfjail *j, const char *username,
893   {
894          const struct passwd *pwd;
895  
896 +        errno = 0;
897          *pwdp = pwd = username ? getpwnam(username) : getpwuid(getuid());
898          if (pwd == NULL) {
899                  if (errno)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines