mirror of
git://github.com/lxc/lxc
synced 2025-09-02 09:49:32 +00:00
lxc-user-nic: check db before trying to delete
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
@@ -3234,7 +3234,7 @@ bool lxc_delete_network(struct lxc_handler *handler)
|
|||||||
if (am_unpriv()) {
|
if (am_unpriv()) {
|
||||||
if (is_ovs_bridge(netdev->link)) {
|
if (is_ovs_bridge(netdev->link)) {
|
||||||
ret = lxc_unpriv_delete_nic(handler->lxcpath,
|
ret = lxc_unpriv_delete_nic(handler->lxcpath,
|
||||||
handler->name, "ovs",
|
handler->name,
|
||||||
netdev, getpid());
|
netdev, getpid());
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
WARN("Failed to remove port \"%s\" "
|
WARN("Failed to remove port \"%s\" "
|
||||||
@@ -5143,12 +5143,11 @@ struct lxc_list *sort_cgroup_settings(struct lxc_list* cgroup_settings)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_unpriv_delete_nic(const char *lxcpath, char *lxcname, char *type,
|
int lxc_unpriv_delete_nic(const char *lxcpath, char *lxcname,
|
||||||
struct lxc_netdev *netdev, pid_t pid)
|
struct lxc_netdev *netdev, pid_t pid)
|
||||||
{
|
{
|
||||||
pid_t child;
|
pid_t child;
|
||||||
int bytes, pipefd[2];
|
int bytes, pipefd[2];
|
||||||
char netdev_link[IFNAMSIZ + 1];
|
|
||||||
char buffer[MAX_BUFFER_SIZE] = {0};
|
char buffer[MAX_BUFFER_SIZE] = {0};
|
||||||
|
|
||||||
if (netdev->type != LXC_NET_VETH) {
|
if (netdev->type != LXC_NET_VETH) {
|
||||||
@@ -5187,20 +5186,19 @@ int lxc_unpriv_delete_nic(const char *lxcpath, char *lxcname, char *type,
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->link)
|
if (!netdev->link)
|
||||||
strncpy(netdev_link, netdev->link, IFNAMSIZ);
|
SYSERROR("Network link for network device \"%s\" is "
|
||||||
else
|
"missing", netdev->priv.veth_attr.pair);
|
||||||
strncpy(netdev_link, "none", IFNAMSIZ);
|
|
||||||
|
|
||||||
ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
|
ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
|
||||||
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
|
if (ret < 0 || ret >= LXC_NUMSTRLEN64)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
|
pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
|
||||||
|
|
||||||
INFO("Execing lxc-user-nic delete %s %s %s ovs %s %s", lxcpath,
|
INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath,
|
||||||
lxcname, pidstr, netdev_link, netdev->priv.veth_attr.pair);
|
lxcname, pidstr, netdev->link, netdev->priv.veth_attr.pair);
|
||||||
execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, "delete", lxcpath,
|
execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, "delete", lxcpath,
|
||||||
lxcname, pidstr, "ovs", netdev_link,
|
lxcname, pidstr, "veth", netdev->link,
|
||||||
netdev->priv.veth_attr.pair, (char *)NULL);
|
netdev->priv.veth_attr.pair, (char *)NULL);
|
||||||
SYSERROR("Failed to exec lxc-user-nic.");
|
SYSERROR("Failed to exec lxc-user-nic.");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@@ -500,7 +500,7 @@ extern FILE *make_anonymous_mount_file(struct lxc_list *mount);
|
|||||||
extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
|
extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
|
||||||
extern unsigned long add_required_remount_flags(const char *s, const char *d,
|
extern unsigned long add_required_remount_flags(const char *s, const char *d,
|
||||||
unsigned long flags);
|
unsigned long flags);
|
||||||
extern int lxc_unpriv_delete_nic(const char *lxcpath, char *lxcname, char *type,
|
extern int lxc_unpriv_delete_nic(const char *lxcpath, char *lxcname,
|
||||||
struct lxc_netdev *netdev, pid_t pid);
|
struct lxc_netdev *netdev, pid_t pid);
|
||||||
|
|
||||||
#endif /* __LXC_CONF_H */
|
#endif /* __LXC_CONF_H */
|
||||||
|
@@ -572,19 +572,22 @@ struct entry_line {
|
|||||||
bool keep;
|
bool keep;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool cull_entries(int fd, char *me, char *t, char *br)
|
static bool cull_entries(int fd, char *me, char *t, char *br, char *nicname,
|
||||||
|
bool *found_nicname)
|
||||||
{
|
{
|
||||||
int i, n = 0;
|
int i, ret;
|
||||||
off_t len;
|
off_t len;
|
||||||
char *buf, *p, *e, *nic;
|
char *buf, *e, *nic, *p;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int n = 0;
|
||||||
struct entry_line *entry_lines = NULL;
|
struct entry_line *entry_lines = NULL;
|
||||||
|
|
||||||
nic = alloca(100);
|
nic = alloca(100);
|
||||||
if (!nic)
|
if (!nic)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fstat(fd, &sb) < 0) {
|
ret = fstat(fd, &sb);
|
||||||
|
if (ret < 0) {
|
||||||
usernic_error("Failed to fstat: %s\n", strerror(errno));
|
usernic_error("Failed to fstat: %s\n", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -593,7 +596,7 @@ static bool cull_entries(int fd, char *me, char *t, char *br)
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
buf = lxc_strmmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (buf == MAP_FAILED) {
|
if (buf == MAP_FAILED) {
|
||||||
usernic_error("Failed to establish shared memory mapping: %s\n",
|
usernic_error("Failed to establish shared memory mapping: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -622,6 +625,10 @@ static bool cull_entries(int fd, char *me, char *t, char *br)
|
|||||||
if (nic && !nic_exists(nic))
|
if (nic && !nic_exists(nic))
|
||||||
entry_lines[n - 1].keep = false;
|
entry_lines[n - 1].keep = false;
|
||||||
|
|
||||||
|
if (nicname)
|
||||||
|
if (!strcmp(nic, nicname))
|
||||||
|
*found_nicname = true;
|
||||||
|
|
||||||
p += entry_lines[n - 1].len + 1;
|
p += entry_lines[n - 1].len + 1;
|
||||||
if (p >= e)
|
if (p >= e)
|
||||||
break;
|
break;
|
||||||
@@ -639,8 +646,9 @@ static bool cull_entries(int fd, char *me, char *t, char *br)
|
|||||||
}
|
}
|
||||||
free(entry_lines);
|
free(entry_lines);
|
||||||
|
|
||||||
munmap(buf, sb.st_size);
|
lxc_strmunmap(buf, sb.st_size);
|
||||||
if (ftruncate(fd, p - buf))
|
ret = ftruncate(fd, p - buf);
|
||||||
|
if (ret < 0)
|
||||||
usernic_error("Failed to set new file size: %s\n",
|
usernic_error("Failed to set new file size: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
||||||
@@ -676,7 +684,7 @@ static char *get_nic_if_avail(int fd, struct alloted_s *names, int pid,
|
|||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
for (n = names; n != NULL; n = n->next)
|
for (n = names; n != NULL; n = n->next)
|
||||||
cull_entries(fd, n->name, intype, br);
|
cull_entries(fd, n->name, intype, br, NULL, NULL);
|
||||||
|
|
||||||
if (allowed == 0)
|
if (allowed == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -965,9 +973,12 @@ struct user_nic_args {
|
|||||||
char *veth_name;
|
char *veth_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LXC_USERNIC_CREATE 0
|
||||||
|
#define LXC_USERNIC_DELETE 1
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd, ifindex, n, pid, ret;
|
int fd, ifindex, n, pid, request, ret;
|
||||||
char *me, *newname;
|
char *me, *newname;
|
||||||
char *cnic = NULL, *nicname = NULL;
|
char *cnic = NULL, *nicname = NULL;
|
||||||
struct alloted_s *alloted = NULL;
|
struct alloted_s *alloted = NULL;
|
||||||
@@ -988,6 +999,15 @@ int main(int argc, char *argv[])
|
|||||||
if (argc >= 8)
|
if (argc >= 8)
|
||||||
args.veth_name = argv[7];
|
args.veth_name = argv[7];
|
||||||
|
|
||||||
|
if (!strcmp(args.cmd, "create")) {
|
||||||
|
request = LXC_USERNIC_CREATE;
|
||||||
|
} else if (!strcmp(args.cmd, "delete")) {
|
||||||
|
request = LXC_USERNIC_DELETE;
|
||||||
|
} else {
|
||||||
|
usage(argv[0], true);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a sane env, because we are setuid-root. */
|
/* Set a sane env, because we are setuid-root. */
|
||||||
ret = clearenv();
|
ret = clearenv();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1029,12 +1049,36 @@ int main(int argc, char *argv[])
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(args.cmd, "delete")) {
|
n = get_alloted(me, args.type, args.link, &alloted);
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (strcmp(args.type, "ovs")) {
|
if (request == LXC_USERNIC_DELETE) {
|
||||||
|
int ret;
|
||||||
|
struct alloted_s *it;
|
||||||
|
bool found_nicname = false;
|
||||||
|
|
||||||
|
if (!is_ovs_bridge(args.link)) {
|
||||||
usernic_error("%s", "Deletion of non ovs type network "
|
usernic_error("%s", "Deletion of non ovs type network "
|
||||||
"devics not implemented\n");
|
"devices not implemented\n");
|
||||||
|
close(fd);
|
||||||
|
free_alloted(&alloted);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether the network device we are supposed to delete
|
||||||
|
* exists in the db. If it doesn't we will not delete it as we
|
||||||
|
* need to assume the network device is not under our control.
|
||||||
|
* As a side effect we also clear any invalid entries from the
|
||||||
|
* database.
|
||||||
|
*/
|
||||||
|
for (it = alloted; it; it = it->next)
|
||||||
|
cull_entries(fd, it->name, args.type, args.link,
|
||||||
|
args.veth_name, &found_nicname);
|
||||||
|
close(fd);
|
||||||
|
free_alloted(&alloted);
|
||||||
|
|
||||||
|
if (!found_nicname) {
|
||||||
|
usernic_error("%s", "Caller is not allowed to delete "
|
||||||
|
"network device\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,10 +1089,9 @@ int main(int argc, char *argv[])
|
|||||||
args.veth_name, args.link);
|
args.veth_name, args.link);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = get_alloted(me, args.type, args.link, &alloted);
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
nicname = get_nic_if_avail(fd, alloted, pid, args.type,
|
nicname = get_nic_if_avail(fd, alloted, pid, args.type,
|
||||||
args.link, n, &cnic);
|
args.link, n, &cnic);
|
||||||
|
Reference in New Issue
Block a user