ipc: read trailing responses after set operation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									f97e81c094
								
							
						
					
					
						commit
						e8fa0f662f
					
				@ -5,6 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <limits.h>
 | 
				
			||||||
#include <net/if.h>
 | 
					#include <net/if.h>
 | 
				
			||||||
#include <netdb.h>
 | 
					#include <netdb.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
@ -30,8 +31,10 @@ static int userspace_set_device(struct wgdevice *dev)
 | 
				
			|||||||
	struct wgpeer *peer;
 | 
						struct wgpeer *peer;
 | 
				
			||||||
	struct wgallowedip *allowedip;
 | 
						struct wgallowedip *allowedip;
 | 
				
			||||||
	FILE *f;
 | 
						FILE *f;
 | 
				
			||||||
	int ret;
 | 
						int ret, set_errno = -EPROTO;
 | 
				
			||||||
	socklen_t addr_len;
 | 
						socklen_t addr_len;
 | 
				
			||||||
 | 
						size_t line_buffer_len = 0, line_len;
 | 
				
			||||||
 | 
						char *key = NULL, *value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = userspace_interface_file(dev->name);
 | 
						f = userspace_interface_file(dev->name);
 | 
				
			||||||
	if (!f)
 | 
						if (!f)
 | 
				
			||||||
@ -92,10 +95,30 @@ static int userspace_set_device(struct wgdevice *dev)
 | 
				
			|||||||
	fprintf(f, "\n");
 | 
						fprintf(f, "\n");
 | 
				
			||||||
	fflush(f);
 | 
						fflush(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fscanf(f, "errno=%d", &ret) != 1)
 | 
						while (getline(&key, &line_buffer_len, f) > 0) {
 | 
				
			||||||
		ret = errno ? -errno : -EPROTO;
 | 
							line_len = strlen(key);
 | 
				
			||||||
	if (getc(f) != '\n' || getc(f) != '\n')
 | 
							ret = set_errno;
 | 
				
			||||||
		ret = -EPROTO;
 | 
							if (line_len == 1 && key[0] == '\n')
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							value = strchr(key, '=');
 | 
				
			||||||
 | 
							if (!value || line_len == 0 || key[line_len - 1] != '\n')
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							*value++ = key[--line_len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!strcmp(key, "errno")) {
 | 
				
			||||||
 | 
								long long num;
 | 
				
			||||||
 | 
								char *end;
 | 
				
			||||||
 | 
								if (value[0] != '-' && !char_is_digit(value[0]))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								num = strtoll(value, &end, 10);
 | 
				
			||||||
 | 
								if (*end || num > INT_MAX || num < INT_MIN)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								set_errno = num;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = errno ? -errno : -EPROTO;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						free(key);
 | 
				
			||||||
	fclose(f);
 | 
						fclose(f);
 | 
				
			||||||
	errno = -ret;
 | 
						errno = -ret;
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user