]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/attach.c
Makefile.am: use right .h file name for seccomp
[mirror_lxc.git] / src / lxc / attach.c
CommitLineData
e0732705
CS
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#define _GNU_SOURCE
25#include <unistd.h>
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <fcntl.h>
31#include <sys/param.h>
32#include <sys/prctl.h>
910bb4fa 33#include <linux/unistd.h>
e0732705
CS
34
35#if !HAVE_DECL_PR_CAPBSET_DROP
36#define PR_CAPBSET_DROP 24
37#endif
38
39#include "namespace.h"
40#include "log.h"
41#include "attach.h"
42#include "caps.h"
43#include "cgroup.h"
44#include "config.h"
45
e0732705
CS
46lxc_log_define(lxc_attach, lxc);
47
48int setns(int fd, int nstype)
49{
50#ifndef __NR_setns
51 errno = ENOSYS;
52 return -1;
53#else
54 return syscall(__NR_setns, fd, nstype);
55#endif
56}
57
58struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
59{
60 struct lxc_proc_context_info *info = calloc(1, sizeof(*info));
61 FILE *proc_file;
62 char proc_fn[MAXPATHLEN];
460a1cf0 63 char *line = NULL;
e0732705 64 size_t line_bufsz = 0;
460a1cf0 65 int ret, found;
e0732705
CS
66
67 if (!info) {
68 SYSERROR("Could not allocate memory.");
69 return NULL;
70 }
71
72 /* read capabilities */
73 snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", pid);
74
75 proc_file = fopen(proc_fn, "r");
76 if (!proc_file) {
77 SYSERROR("Could not open %s", proc_fn);
78 goto out_error;
79 }
80
81 found = 0;
82 while (getline(&line, &line_bufsz, proc_file) != -1) {
83 ret = sscanf(line, "CapBnd: %llx", &info->capability_mask);
84 if (ret != EOF && ret > 0) {
85 found = 1;
86 break;
87 }
88 }
89
90 fclose(proc_file);
91
92 if (!found) {
93 SYSERROR("Could not read capability bounding set from %s", proc_fn);
94 errno = ENOENT;
95 goto out_error;
96 }
97
98 /* read personality */
99 snprintf(proc_fn, MAXPATHLEN, "/proc/%d/personality", pid);
100
101 proc_file = fopen(proc_fn, "r");
102 if (!proc_file) {
103 SYSERROR("Could not open %s", proc_fn);
104 goto out_error;
105 }
106
107 ret = fscanf(proc_file, "%lx", &info->personality);
108 fclose(proc_file);
109
110 if (ret == EOF || ret == 0) {
111 SYSERROR("Could not read personality from %s", proc_fn);
112 errno = ENOENT;
113 goto out_error;
114 }
115
e0732705
CS
116 return info;
117
118out_error:
460a1cf0 119 free(info);
e0732705
CS
120 free(line);
121 return NULL;
122}
123
99d50954
CS
124int lxc_attach_to_ns(pid_t pid)
125{
126 char path[MAXPATHLEN];
127 char *ns[] = { "pid", "mnt", "net", "ipc", "uts" };
128 const int size = sizeof(ns) / sizeof(char *);
129 int fd[size];
130 int i;
131
132 snprintf(path, MAXPATHLEN, "/proc/%d/ns", pid);
133 if (access(path, X_OK)) {
134 ERROR("Does this kernel version support 'attach' ?");
135 return -1;
136 }
137
138 for (i = 0; i < size; i++) {
139 snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]);
140 fd[i] = open(path, O_RDONLY);
141 if (fd[i] < 0) {
142 SYSERROR("failed to open '%s'", path);
143 return -1;
144 }
145 }
146
147 for (i = 0; i < size; i++) {
148 if (setns(fd[i], 0)) {
149 SYSERROR("failed to set namespace '%s'", ns[i]);
150 return -1;
151 }
152
153 close(fd[i]);
154 }
155
156 return 0;
157}
158
e0732705
CS
159int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx)
160{
161 int last_cap = lxc_caps_last_cap();
162 int cap;
163
164 for (cap = 0; cap <= last_cap; cap++) {
165 if (ctx->capability_mask & (1LL << cap))
166 continue;
167
168 if (prctl(PR_CAPBSET_DROP, cap, 0, 0, 0)) {
169 SYSERROR("failed to remove capability id %d", cap);
170 return -1;
171 }
172 }
173
174 return 0;
175}