Description:
add option -A <opt> to box. This options allow more argument to be explicitly passed to the program We have to use this because if the argument we wish to pass to the program is option (in -? format), box will intepret it as its option and failed accordingly. be noted that, by the definition of getopt, these options will be put after original argument (check the code for more info)
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r186:c8d646326d0a - - 1 file changed: 17 inserted, 4 deleted

@@ -1563,185 +1563,198
1563 1563 }
1564 1564 }
1565 1565 else
1566 1566 die("wait4: unknown status %x, giving up!", stat);
1567 1567 }
1568 1568 }
1569 1569
1570 1570 static void
1571 1571 box_inside(int argc, char **argv)
1572 1572 {
1573 1573 struct rlimit rl;
1574 1574 char *args[argc+1];
1575 1575
1576 1576 memcpy(args, argv, argc * sizeof(char *));
1577 1577 args[argc] = NULL;
1578 1578 if (set_cwd && chdir(set_cwd))
1579 1579 die("chdir: %m");
1580 1580 if (redir_stdin)
1581 1581 {
1582 1582 close(0);
1583 1583 if (open(redir_stdin, O_RDONLY) != 0)
1584 1584 die("open(\"%s\"): %m", redir_stdin);
1585 1585 }
1586 1586 if (redir_stdout)
1587 1587 {
1588 1588 close(1);
1589 1589 if (open(redir_stdout, O_WRONLY | O_CREAT | O_TRUNC, 0666) != 1)
1590 1590 die("open(\"%s\"): %m", redir_stdout);
1591 1591 }
1592 1592 if (redir_stderr)
1593 1593 {
1594 1594 close(2);
1595 1595 if (open(redir_stderr, O_WRONLY | O_CREAT | O_TRUNC, 0666) != 2)
1596 1596 die("open(\"%s\"): %m", redir_stderr);
1597 1597 }
1598 1598 else
1599 1599 dup2(1, 2);
1600 1600 setpgrp();
1601 1601
1602 1602 if (memory_limit)
1603 1603 {
1604 1604 rl.rlim_cur = rl.rlim_max = memory_limit * 1024;
1605 1605 if (setrlimit(RLIMIT_AS, &rl) < 0)
1606 1606 die("setrlimit(RLIMIT_AS): %m");
1607 1607 }
1608 1608
1609 1609 rl.rlim_cur = rl.rlim_max = (stack_limit ? (rlim_t)stack_limit * 1024 : RLIM_INFINITY);
1610 1610 if (setrlimit(RLIMIT_STACK, &rl) < 0)
1611 1611 die("setrlimit(RLIMIT_STACK): %m");
1612 1612
1613 1613 rl.rlim_cur = rl.rlim_max = 64;
1614 1614 if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
1615 1615 die("setrlimit(RLIMIT_NOFILE): %m");
1616 1616
1617 1617 char **env = setup_environment();
1618 1618 if (filter_syscalls)
1619 1619 {
1620 1620 if (ptrace(PTRACE_TRACEME) < 0)
1621 1621 die("ptrace(PTRACE_TRACEME): %m");
1622 1622 /* Trick: Make sure that we are stopped until the boxkeeper wakes up. */
1623 1623 raise(SIGSTOP);
1624 1624 }
1625 1625 execve(args[0], args, env);
1626 1626 die("execve(\"%s\"): %m", args[0]);
1627 1627 }
1628 1628
1629 1629 static void
1630 1630 usage(void)
1631 1631 {
1632 1632 fprintf(stderr, "Invalid arguments!\n");
1633 1633 printf("\
1634 1634 Usage: box [<options>] -- <command> <arguments>\n\
1635 1635 \n\
1636 1636 Options:\n\
1637 1637 -a <level>\tSet file access level (0=none, 1=cwd, 2=/etc,/lib,..., 3=whole fs, 9=no checks; needs -f)\n\
1638 1638 -c <dir>\tChange directory to <dir> first\n\
1639 1639 -e\t\tInherit full environment of the parent process\n\
1640 1640 -E <var>\tInherit the environment variable <var> from the parent process\n\
1641 1641 -E <var>=<val>\tSet the environment variable <var> to <val>; unset it if <var> is empty\n\
1642 1642 -f\t\tFilter system calls (-ff=very restricted)\n\
1643 1643 -i <file>\tRedirect stdin from <file>\n\
1644 1644 -k <size>\tLimit stack size to <size> KB (default: 0=unlimited)\n\
1645 1645 -m <size>\tLimit address space to <size> KB\n\
1646 1646 -M <file>\tOutput process information to <file> (name:value)\n\
1647 1647 -o <file>\tRedirect stdout to <file>\n\
1648 1648 -p <path>\tPermit access to the specified path (or subtree if it ends with a `/')\n\
1649 1649 -p <path>=<act>\tDefine action for the specified path (<act>=yes/no)\n\
1650 1650 -r <file>\tRedirect stderr to <file>\n\
1651 1651 -s <sys>\tPermit the specified syscall (be careful)\n\
1652 1652 -s <sys>=<act>\tDefine action for the specified syscall (<act>=yes/no/file)\n\
1653 1653 -t <time>\tSet run time limit (seconds, fractions allowed)\n\
1654 1654 -T\t\tAllow syscalls for measuring run time\n\
1655 1655 -v\t\tBe verbose (use multiple times for even more verbosity)\n\
1656 1656 -w <time>\tSet wall clock time limit (seconds, fractions allowed)\n\
1657 1657 -x <time>\tSet extra timeout, before which a timing-out program is not yet killed,\n\
1658 1658 \t\tso that its real execution time is reported (seconds, fractions allowed)\n\
1659 + -A <opt>\tPass <opt> as additional argument to the <command>\n\
1660 + \t\tBe noted that this option will be appended after <arguments> respectively\n\
1659 1661 ");
1660 1662 exit(2);
1661 1663 }
1662 1664
1663 1665 int
1664 1666 main(int argc, char **argv)
1665 1667 {
1666 1668 int c;
1667 1669 uid_t uid;
1670 + char **prog_argv = xmalloc(sizeof(char*) * argc);
1671 + int prog_argc = 0;
1668 1672
1669 - while ((c = getopt(argc, argv, "a:c:eE:fi:k:m:M:o:p:r:s:t:Tvw:x:")) >= 0)
1673 + while ((c = getopt(argc, argv, "a:c:eE:fi:k:m:M:o:p:r:s:t:Tvw:x:A:")) >= 0)
1670 1674 switch (c)
1671 1675 {
1672 1676 case 'a':
1673 1677 file_access = atol(optarg);
1674 1678 break;
1675 1679 case 'c':
1676 1680 set_cwd = optarg;
1677 1681 break;
1678 1682 case 'e':
1679 1683 pass_environ = 1;
1680 1684 break;
1681 1685 case 'E':
1682 1686 if (!set_env_action(optarg))
1683 1687 usage();
1684 1688 break;
1685 1689 case 'f':
1686 1690 filter_syscalls++;
1687 1691 break;
1688 1692 case 'k':
1689 1693 stack_limit = atol(optarg);
1690 1694 break;
1691 1695 case 'i':
1692 1696 redir_stdin = optarg;
1693 1697 break;
1694 1698 case 'm':
1695 1699 memory_limit = atol(optarg);
1696 1700 break;
1697 1701 case 'M':
1698 1702 meta_open(optarg);
1699 1703 break;
1700 1704 case 'o':
1701 1705 redir_stdout = optarg;
1702 1706 break;
1703 1707 case 'p':
1704 1708 if (!set_path_action(optarg))
1705 1709 usage();
1706 1710 break;
1707 1711 case 'r':
1708 1712 redir_stderr = optarg;
1709 1713 break;
1710 1714 case 's':
1711 1715 if (!set_syscall_action(optarg))
1712 1716 usage();
1713 1717 break;
1714 1718 case 't':
1715 1719 timeout = 1000*atof(optarg);
1716 1720 break;
1717 1721 case 'T':
1718 1722 syscall_action[__NR_times] = A_YES;
1719 1723 break;
1720 1724 case 'v':
1721 1725 verbose++;
1722 1726 break;
1723 1727 case 'w':
1724 1728 wall_timeout = 1000*atof(optarg);
1725 1729 break;
1726 1730 case 'x':
1727 1731 extra_timeout = 1000*atof(optarg);
1732 + case 'A':
1733 + prog_argv[prog_argc++] = strdup(optarg);
1734 + break;
1728 1735 break;
1729 1736 default:
1730 1737 usage();
1731 1738 }
1732 1739 if (optind >= argc)
1733 1740 usage();
1734 1741
1735 1742 sanity_check();
1736 1743 uid = geteuid();
1737 1744 if (setreuid(uid, uid) < 0)
1738 1745 die("setreuid: %m");
1739 1746 box_pid = fork();
1740 1747 if (box_pid < 0)
1741 1748 die("fork: %m");
1742 - if (!box_pid)
1743 - box_inside(argc-optind, argv+optind);
1744 - else
1749 + if (!box_pid) {
1750 + int real_argc = prog_argc + argc - optind;
1751 + char **real_argv = xmalloc(sizeof(char*) * (real_argc));
1752 + for (int i = 0;i < argc-optind;i++)
1753 + real_argv[i] = strdup(argv[i+optind]);
1754 + for (int i = 0;i < prog_argc;i++)
1755 + real_argv[argc - optind + i] = strdup(prog_argv[i]);
1756 + box_inside(real_argc, real_argv);
1757 + } else
1745 1758 boxkeeper();
1746 1759 die("Internal error: fell over edge of the world");
1747 1760 }
You need to be logged in to leave comments. Login now