/* preload given regular device to channel */ static void RegularChannel(struct ChannelDesc* channel, int n) { int h; ZLOGS(LOG_DEBUG, "preload regular %s", channel->alias); switch(CH_RW_TYPE(channel)) { case 1: /* read only */ h = open(CH_NAME(channel, n), O_RDONLY, CHANNEL_RIGHTS); CH_HANDLE(channel, n) = GINT_TO_POINTER(h); channel->size = GetFileSize(CH_NAME(channel, n)); ZLOGFAIL(channel->size < 0, EFAULT, "cannot open %s", CH_NAME(channel, n)); break; case 2: /* write only. existing file will be overwritten */ h = open(CH_NAME(channel, n), O_WRONLY|O_CREAT|O_TRUNC, CHANNEL_RIGHTS); CH_HANDLE(channel, n) = GINT_TO_POINTER(h); channel->size = 0; if(g_strcmp0(CH_NAME(channel, n), DEV_NULL) != 0) PreallocateChannel(channel, n); break; case 3: /* cdr or full random access */ ZLOGFAIL(channel->type == SGetSPut, EFAULT, "sequential channels cannot have r/w access"); ZLOGFAIL(channel->type == SGetRPut, EFAULT, "sequential read / random write channels not supported"); /* open the file and ensure that putpos is not greater than the file size */ h = open(CH_NAME(channel, n), O_RDWR | O_CREAT, CHANNEL_RIGHTS); CH_HANDLE(channel, n) = GINT_TO_POINTER(h); channel->size = GetFileSize(CH_NAME(channel, n)); ZLOGFAIL(channel->size < 0, EFAULT, "cannot open %s", CH_NAME(channel, n)); ZLOGFAIL(channel->putpos > channel->size, EFAULT, "%s size is less then specified append position", CH_NAME(channel, n)); /* file does not exist */ if(channel->size == 0 && g_strcmp0(CH_NAME(channel, n), DEV_NULL) != 0) PreallocateChannel(channel, n); /* existing file */ else channel->putpos = channel->type == RGetSPut ? channel->size : 0; break; default: ZLOGFAIL(1, EINVAL, "%s has invalid i/o type", channel->alias); break; } ZLOGFAIL(GPOINTER_TO_INT(CH_HANDLE(channel, n)) < 0, errno, "%s open error", CH_NAME(channel, n)); }
/* * preload given file (channel). return 0 if success, otherwise negative errcode */ int PreloadChannel(struct NaClApp *nap, struct PreOpenedFileDesc* channel) { /* debug checks */ if(!channel->name) return -1; /* channel is not constructed. skip it */ COND_ABORT(channel->mounted != LOADED, "channel is not supposed to be loaded\n"); /* open file */ channel->handle = open((char*)channel->name, GetChannelOpenFlags(channel), S_IRWXU); COND_ABORT(channel->handle < 0, "channel open error\n"); /* check if given file in bounds of manifest limits */ channel->fsize = GetFileSize((char*)channel->name); PreallocateChannel(channel); COND_ABORT(channel->max_size < channel->fsize, "channel legnth exceeded policy limit\n"); /* mounting finalization */ channel->bsize = -1; /* will be provided by user */ return 0; }
/* * premap given file (channel). return 0 if success, otherwise negative errcode * note: malloc() */ int PremapChannel(struct NaClApp *nap, struct PreOpenedFileDesc* channel) { int desc; struct NaClHostDesc *hd = malloc(sizeof(*hd)); /* debug checks */ COND_ABORT(!hd, "cannot allocate memory to hold channel descriptor\n"); COND_ABORT(!channel, "channel is not constructed\n"); COND_ABORT(channel->mounted != MAPPED, "channel is not supposed to be mapped\n"); COND_ABORT(!channel->name, "cannot resolve channel name\n"); /* open file */ channel->handle = open((char*)channel->name, GetChannelOpenFlags(channel), S_IRWXU); COND_ABORT(channel->handle < 0, "channel open error\n"); /* check if given file in bounds of manifest limits */ channel->fsize = GetFileSize((char*)channel->name); PreallocateChannel(channel); COND_ABORT(channel->max_size < channel->fsize, "channel legnth exceeded policy limit\n"); /* construct nacl descriptor */ hd->d = channel->handle; desc = NaClSetAvail(nap, ((struct NaClDesc *) NaClDescIoDescMake(hd))); /* map whole file into the memory. address cannot be higher than stack */ channel->buffer = NaClCommonSysMmapIntern(nap, NULL, channel->fsize, GetChannelMapProt(channel), GetChannelMapFlags(channel), desc, 0); COND_ABORT((uint32_t)channel->buffer > 0xFF000000, "channel map error\n"); /* mounting finalization */ close(channel->handle); channel->bsize = channel->fsize; /* yes. mapped file always put to memory whole */ channel->handle = -1; /* there is no opened file for mapped channel */ return 0; }