/* * netsniff-ng - the packet sniffing beast * Copyright 2011 Daniel Borkmann. * Subject to the GPL, version 2. */ #include #include #include #include #include #include #include "die.h" #include "str.h" #include "built_in.h" #include "locking.h" #include "xmalloc.h" #include "curvetun.h" #include "curve.h" #include "curvetun_mgmt_servers.h" #include "crypto.h" struct server_store { int udp; char alias[256]; char host[256]; char port[6]; /* 5 + \0 */ unsigned char publickey[crypto_box_pub_key_size]; struct curve25519_proto proto_inf; unsigned char auth_token[crypto_auth_hmacsha512256_KEYBYTES]; struct server_store *next; }; static struct server_store *store = NULL; static struct server_store *selected = NULL; static struct rwlock store_lock; static struct server_store *server_store_alloc(void) { return xzmalloc(sizeof(struct server_store)); } static void server_store_free(struct server_store *ss) { if (!ss) return; memset(ss, 0, sizeof(struct server_store)); xfree(ss); } enum parse_states { PARSE_ALIAS, PARSE_SERVER, PARSE_PORT, PARSE_CARRIER, PARSE_PUBKEY, PARSE_DONE, }; static int parse_line(char *line, char *homedir) { char *str; enum parse_states s = PARSE_ALIAS; struct server_store *elem; unsigned char pkey[crypto_box_pub_key_size]; elem = server_store_alloc(); elem->next = store; str = strtok(line, ";"); for (; str != NULL;) { switch (s) { case PARSE_ALIAS: strlcpy(elem->alias, str, sizeof(elem->alias)); s = PARSE_SERVER; break; case PARSE_SERVER: strlcpy(elem->host, str, sizeof(elem->host)); s = PARSE_PORT; break; case PARSE_PORT: strlcpy(elem->port, str, sizeof(elem->port)); s = PARSE_CARRIER; break; case PARSE_CARRIER: if (!strncmp("udp", str, strlen("udp"))) elem->udp = 1; else if (!strncmp("tcp", str, strlen("tcp"))) elem->udp = 0; else { syslog(LOG_ERR, "Incorrect carrier type !(udp|tcp) in server spec.\n"); return -EIO; } s = PARSE_PUBKEY; break; case PARSE_PUBKEY: if (!curve25519_pubkey_hexparse_32(pkey, sizeof(pkey), str, strlen(str))) return -EINVAL; memcpy(elem->publickey, pkey, sizeof(elem->publickey)); memcpy(elem->auth_token, pkey, sizeof(elem->auth_token)); curve25519_proto_init(&elem->proto_inf, elem->publickey, sizeof(elem->publickey)); s = PARSE_DONE; break; case PARSE_DONE: break; default: return -EIO; } str = strtok(NULL, ";"); } store = elem; return s == PARSE_DONE ? 0 : -EIO; } void parse_userfile_and_generate_serv_store_or_die(char *homedir) { FILE *fp; char path[PATH_MAX], buff[1024]; int line = 1, ret; memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS); rwlock_init(&store_lock); rwlock_wr_lock(&store_lock); fp = fopen(path, "r"); if (!fp) panic("Cannot open server file!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; /* A comment. Skip this line */ if (buff[0] == '#' || buff[0] == '\n') { memset(buff, 0, sizeof(buff)); line++; continue; } ret = parse_line(buff, homedir); if (ret < 0) panic("Cannot parse line %d from clients!\n", line); line++; memset(buff, 0, sizeof(buff)); } fclose(fp); if (store == NULL) panic("No registered servers found!\n"); rwlock_unlock(&store_lock); } void dump_serv_store(void) { int i; struct server_store *elem; rwlock_rd_lock(&store_lock); elem = store; while (elem) { printf("[%s] -> %s:%s via %s -> ", elem->alias, elem->host, elem->port, elem->udp ? "udp" : "tcp"); for (i = 0; i < sizeof(elem->publickey); ++i) if (i == (sizeof(elem->publickey) - 1)) printf("%02x\n", (unsigned char) elem->publickey[i]); else printf("%02x:", (unsigned char) elem->publickey[i]); elem = elem->next; } rwlock_unlock(&store_lock); } void destroy_serv_store(void) { struct server_store *elem, *nelem = NULL; rwlock_wr_lock(&store_lock); selected = NULL; elem = store; while (elem) { nelem = elem->next; elem->next = NULL; server_store_free(elem); elem = nelem; } rwlock_unlock(&store_lock); rwlock_destroy(&store_lock); } void get_serv_store_entry_by_alias(char *alias, size_t len, char **host, char **port, int *udp) { struct server_store *elem; rwlock_rd_lock(&store_lock); elem = store; if (!alias) { while (elem && elem->next) elem = elem->next; if (elem) { (*host) = elem->host; (*port) = elem->port; (*udp) = elem->udp; selected = elem; } else { rwlock_unlock(&store_lock); goto nothing; } } else { while (elem) { if (!strncmp(elem->alias, alias, min(len, strlen(elem->alias) + 1))) break; elem = elem->next; } if (elem) { (*host) = elem->host; (*port) = elem->port; (*udp) = elem->udp; selected = elem; } else { rwlock_unlock(&store_lock); goto nothing; } } rwlock_unlock(&store_lock); return; nothing: (*host) = NULL; (*port) = NULL; (*udp) = -1; } struct curve25519_proto *get_serv_store_entry_proto_inf(void) { struct curve25519_proto *ret = NULL; rwlock_rd_lock(&store_lock); if (selected) ret = &selected->proto_inf; rwlock_unlock(&store_lock); return ret; } unsigned char *get_serv_store_entry_auth_token(void) { unsigned char *ret = NULL; rwlock_rd_lock(&store_lock); if (selected) ret = selected->auth_token; rwlock_unlock(&store_lock); return ret; } ux/net-next.git/tree/?h=nds-private-remove&id=54791b276b4000b307339f269d3bf7db877d536f'>1c2616bd373ce5ea28aac2a53e32f5b5834901ce /sound/ppc/awacs.c parent5d0e7705774dd412a465896d08d59a81a345c1e4 (diff)parent047487241ff59374fded8c477f21453681f5995c (diff)
Merge branch 'sparc64-non-resumable-user-error-recovery'
Liam R. Howlett says: ==================== sparc64: Recover from userspace non-resumable PIO & MEM errors A non-resumable error from userspace is able to cause a kernel panic or trap loop due to the setup and handling of the queued traps once in the kernel. This patch series addresses both of these issues. The queues are fixed by simply zeroing the memory before use. PIO errors from userspace will result in a SIGBUS being sent to the user process. The MEM errors form userspace will result in a SIGKILL and also cause the offending pages to be claimed so they are no longer used in future tasks. SIGKILL is used to ensure that the process does not try to coredump and result in an attempt to read the memory again from within kernel space. Although there is a HV call to scrub the memory (mem_scrub), there is no easy way to guarantee that the real memory address(es) are not used by other tasks. Clearing the error with mem_scrub would zero the memory and cause the other processes to proceed with bad data. The handling of other non-resumable errors remain unchanged and will cause a panic. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'sound/ppc/awacs.c')