16cd6a6acSopenharmony_ci#include <unistd.h> 26cd6a6acSopenharmony_ci#include <fcntl.h> 36cd6a6acSopenharmony_ci#include <string.h> 46cd6a6acSopenharmony_ci#include <stdlib.h> 56cd6a6acSopenharmony_ci#include <errno.h> 66cd6a6acSopenharmony_ci#include <sys/socket.h> 76cd6a6acSopenharmony_ci#include "selinux_internal.h" 86cd6a6acSopenharmony_ci#include "policy.h" 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ci#ifndef SO_PEERSEC 116cd6a6acSopenharmony_ci#define SO_PEERSEC 31 126cd6a6acSopenharmony_ci#endif 136cd6a6acSopenharmony_ci 146cd6a6acSopenharmony_ciint getpeercon_raw(int fd, char ** context) 156cd6a6acSopenharmony_ci{ 166cd6a6acSopenharmony_ci char *buf; 176cd6a6acSopenharmony_ci socklen_t size; 186cd6a6acSopenharmony_ci ssize_t ret; 196cd6a6acSopenharmony_ci 206cd6a6acSopenharmony_ci size = INITCONTEXTLEN + 1; 216cd6a6acSopenharmony_ci buf = malloc(size); 226cd6a6acSopenharmony_ci if (!buf) 236cd6a6acSopenharmony_ci return -1; 246cd6a6acSopenharmony_ci memset(buf, 0, size); 256cd6a6acSopenharmony_ci 266cd6a6acSopenharmony_ci ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size); 276cd6a6acSopenharmony_ci if (ret < 0 && errno == ERANGE) { 286cd6a6acSopenharmony_ci char *newbuf; 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci newbuf = realloc(buf, size); 316cd6a6acSopenharmony_ci if (!newbuf) 326cd6a6acSopenharmony_ci goto out; 336cd6a6acSopenharmony_ci 346cd6a6acSopenharmony_ci buf = newbuf; 356cd6a6acSopenharmony_ci memset(buf, 0, size); 366cd6a6acSopenharmony_ci ret = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &size); 376cd6a6acSopenharmony_ci } 386cd6a6acSopenharmony_ci out: 396cd6a6acSopenharmony_ci if (ret < 0) 406cd6a6acSopenharmony_ci free(buf); 416cd6a6acSopenharmony_ci else 426cd6a6acSopenharmony_ci *context = buf; 436cd6a6acSopenharmony_ci return ret; 446cd6a6acSopenharmony_ci} 456cd6a6acSopenharmony_ci 466cd6a6acSopenharmony_ci 476cd6a6acSopenharmony_ciint getpeercon(int fd, char ** context) 486cd6a6acSopenharmony_ci{ 496cd6a6acSopenharmony_ci int ret; 506cd6a6acSopenharmony_ci char * rcontext; 516cd6a6acSopenharmony_ci 526cd6a6acSopenharmony_ci ret = getpeercon_raw(fd, &rcontext); 536cd6a6acSopenharmony_ci 546cd6a6acSopenharmony_ci if (!ret) { 556cd6a6acSopenharmony_ci ret = selinux_raw_to_trans_context(rcontext, context); 566cd6a6acSopenharmony_ci freecon(rcontext); 576cd6a6acSopenharmony_ci } 586cd6a6acSopenharmony_ci 596cd6a6acSopenharmony_ci return ret; 606cd6a6acSopenharmony_ci} 61