inline char* readstring(){ //Read a Pascal string with 1 length byte unsigned length = readint8(); char *string = (char*) malloc(length+1); readbytes(string, length); string[length] = '\0'; return string; }
static struct nsenter_config process_nl_attributes(int pipenum, char *data, int data_size) { struct nsenter_config config = {0}; struct nlattr *nlattr; int payload_len; int start = 0; config.consolefd = -1; while (start < data_size) { nlattr = (struct nlattr *)(data + start); start += NLA_HDRLEN; payload_len = nlattr->nla_len - NLA_HDRLEN; if (nlattr->nla_type == CLONE_FLAGS_ATTR) { config.cloneflags = readint32(data + start); } else if (nlattr->nla_type == CONSOLE_PATH_ATTR) { // get the console path before setns because it may // change mnt namespace config.consolefd = open(data + start, O_RDWR); if (config.consolefd < 0) { pr_perror("Failed to open console %s", data + start); exit(1); } } else if (nlattr->nla_type == NS_PATHS_ATTR) { // if custom namespaces are required, open all // descriptors and perform setns on them int i, j; int nslen = num_namespaces(data + start); int fds[nslen]; char *nslist[nslen]; char *ns; char *saveptr; for (i = 0; i < nslen; i++) { char *str = NULL; if (i == 0) { str = data + start; } ns = strtok_r(str, ",", &saveptr); if (ns == NULL) { break; } fds[i] = open(ns, O_RDONLY); if (fds[i] == -1) { for (j = 0; j < i; j++) { close(fds[j]); } pr_perror("Failed to open %s", ns); exit(1); } nslist[i] = ns; } for (i = 0; i < nslen; i++) { if (setns(fds[i], 0) != 0) { pr_perror("Failed to setns to %s", nslist[i]); exit(1); } close(fds[i]); } } else if (nlattr->nla_type == UIDMAP_ATTR) { config.uidmap = data + start; config.uidmap_len = payload_len; } else if (nlattr->nla_type == GIDMAP_ATTR) { config.gidmap = data + start; config.gidmap_len = payload_len; } else if (nlattr->nla_type == SETGROUP_ATTR) { config.is_setgroup = readint8(data + start); } else { pr_perror("Unknown netlink message type %d", nlattr->nla_type); exit(1); } start += NLA_ALIGN(payload_len); } return config; }