Bug Summary

File:os/unix/ngx_files.c
Location:line 187, column 30
Description:Access to field 'iov_len' results in a dereference of a null pointer (loaded from variable 'iov')

Annotated Source Code

1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8#include <ngx_config.h>
9#include <ngx_core.h>
10
11
12#if (NGX_HAVE_FILE_AIO)
13
14ngx_uint_t ngx_file_aio = 1;
15
16#endif
17
18
19ssize_t
20ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
21{
22 ssize_t n;
23
24 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
25 "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
26
27#if (NGX_HAVE_PREAD1)
28
29 n = pread(file->fd, buf, size, offset);
30
31 if (n == -1) {
32 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "pread() \"%s\" failed", file->
name.data)
33 "pread() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "pread() \"%s\" failed", file->
name.data)
;
34 return NGX_ERROR-1;
35 }
36
37#else
38
39 if (file->sys_offset != offset) {
40 if (lseek(file->fd, offset, SEEK_SET0) == -1) {
41 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
42 "lseek() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
;
43 return NGX_ERROR-1;
44 }
45
46 file->sys_offset = offset;
47 }
48
49 n = read(file->fd, buf, size);
50
51 if (n == -1) {
52 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "read() \"%s\" failed", file->
name.data)
53 "read() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "read() \"%s\" failed", file->
name.data)
;
54 return NGX_ERROR-1;
55 }
56
57 file->sys_offset += n;
58
59#endif
60
61 file->offset += n;
62
63 return n;
64}
65
66
67ssize_t
68ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
69{
70 ssize_t n, written;
71
72 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
73 "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
74
75 written = 0;
76
77#if (NGX_HAVE_PWRITE1)
78
79 for ( ;; ) {
80 n = pwrite(file->fd, buf + written, size, offset);
81
82 if (n == -1) {
83 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "pwrite() \"%s\" failed", file
->name.data)
84 "pwrite() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "pwrite() \"%s\" failed", file
->name.data)
;
85 return NGX_ERROR-1;
86 }
87
88 file->offset += n;
89 written += n;
90
91 if ((size_t) n == size) {
92 return written;
93 }
94
95 offset += n;
96 size -= n;
97 }
98
99#else
100
101 if (file->sys_offset != offset) {
102 if (lseek(file->fd, offset, SEEK_SET0) == -1) {
103 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
104 "lseek() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
;
105 return NGX_ERROR-1;
106 }
107
108 file->sys_offset = offset;
109 }
110
111 for ( ;; ) {
112 n = write(file->fd, buf + written, size);
113
114 if (n == -1) {
115 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "write() \"%s\" failed", file->
name.data)
116 "write() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "write() \"%s\" failed", file->
name.data)
;
117 return NGX_ERROR-1;
118 }
119
120 file->offset += n;
121 written += n;
122
123 if ((size_t) n == size) {
124 return written;
125 }
126
127 size -= n;
128 }
129#endif
130}
131
132
133ngx_fd_t
134ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
135{
136 ngx_fd_t fd;
137
138 fd = open((const char *) name, O_CREAT0x0200|O_EXCL0x0800|O_RDWR0x0002,
139 access ? access : 0600);
140
141 if (fd != -1 && !persistent) {
142 (void) unlink((const char *) name);
143 }
144
145 return fd;
146}
147
148
149#define NGX_IOVS8 8
150
151ssize_t
152ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
153 ngx_pool_t *pool)
154{
155 u_char *prev;
156 size_t size;
157 ssize_t total, n;
158 ngx_array_t vec;
159 struct iovec *iov, iovs[NGX_IOVS8];
160
161 /* use pwrite() if there is the only buf in a chain */
162
163 if (cl->next == NULL((void*)0)) {
1
Taking false branch
164 return ngx_write_file(file, cl->buf->pos,
165 (size_t) (cl->buf->last - cl->buf->pos),
166 offset);
167 }
168
169 total = 0;
170
171 vec.elts = iovs;
172 vec.size = sizeof(struct iovec);
173 vec.nalloc = NGX_IOVS8;
174 vec.pool = pool;
175
176 do {
177 prev = NULL((void*)0);
178 iov = NULL((void*)0);
2
Null pointer value stored to 'iov'
179 size = 0;
180
181 vec.nelts = 0;
182
183 /* create the iovec and coalesce the neighbouring bufs */
184
185 while (cl && vec.nelts < IOV_MAX1024) {
3
Loop condition is true. Entering loop body
186 if (prev == cl->buf->pos) {
4
Taking true branch
187 iov->iov_len += cl->buf->last - cl->buf->pos;
5
Access to field 'iov_len' results in a dereference of a null pointer (loaded from variable 'iov')
188
189 } else {
190 iov = ngx_array_push(&vec);
191 if (iov == NULL((void*)0)) {
192 return NGX_ERROR-1;
193 }
194
195 iov->iov_base = (void *) cl->buf->pos;
196 iov->iov_len = cl->buf->last - cl->buf->pos;
197 }
198
199 size += cl->buf->last - cl->buf->pos;
200 prev = cl->buf->last;
201 cl = cl->next;
202 }
203
204 /* use pwrite() if there is the only iovec buffer */
205
206 if (vec.nelts == 1) {
207 iov = vec.elts;
208
209 n = ngx_write_file(file, (u_char *) iov[0].iov_base,
210 iov[0].iov_len, offset);
211
212 if (n == NGX_ERROR-1) {
213 return n;
214 }
215
216 return total + n;
217 }
218
219 if (file->sys_offset != offset) {
220 if (lseek(file->fd, offset, SEEK_SET0) == -1) {
221 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
222 "lseek() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "lseek() \"%s\" failed", file->
name.data)
;
223 return NGX_ERROR-1;
224 }
225
226 file->sys_offset = offset;
227 }
228
229 n = writev(file->fd, vec.elts, vec.nelts);
230
231 if (n == -1) {
232 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "writev() \"%s\" failed", file
->name.data)
233 "writev() \"%s\" failed", file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, (*__error()), "writev() \"%s\" failed", file
->name.data)
;
234 return NGX_ERROR-1;
235 }
236
237 if ((size_t) n != size) {
238 ngx_log_error(NGX_LOG_CRIT, file->log, 0,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, 0, "writev() \"%s\" has written only %z of %uz"
, file->name.data, n, size)
239 "writev() \"%s\" has written only %z of %uz",if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, 0, "writev() \"%s\" has written only %z of %uz"
, file->name.data, n, size)
240 file->name.data, n, size)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, 0, "writev() \"%s\" has written only %z of %uz"
, file->name.data, n, size)
;
241 return NGX_ERROR-1;
242 }
243
244 ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
245 "writev: %d, %z", file->fd, n);
246
247 file->sys_offset += n;
248 file->offset += n;
249 offset += n;
250 total += n;
251
252 } while (cl);
253
254 return total;
255}
256
257
258ngx_int_t
259ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
260{
261 struct timeval tv[2];
262
263 tv[0].tv_sec = ngx_time()ngx_cached_time->sec;
264 tv[0].tv_usec = 0;
265 tv[1].tv_sec = s;
266 tv[1].tv_usec = 0;
267
268 if (utimes((char *) name, tv) != -1) {
269 return NGX_OK0;
270 }
271
272 return NGX_ERROR-1;
273}
274
275
276ngx_int_t
277ngx_create_file_mapping(ngx_file_mapping_t *fm)
278{
279 fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,open((const char *) fm->name, 0x0002|0x0200|0x0400, 0644)
280 NGX_FILE_DEFAULT_ACCESS)open((const char *) fm->name, 0x0002|0x0200|0x0400, 0644);
281 if (fm->fd == NGX_INVALID_FILE-1) {
282 ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "open()" " \"%s\" failed", fm->
name)
283 ngx_open_file_n " \"%s\" failed", fm->name)if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "open()" " \"%s\" failed", fm->
name)
;
284 return NGX_ERROR-1;
285 }
286
287 if (ftruncate(fm->fd, fm->size) == -1) {
288 ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "ftruncate() \"%s\" failed", fm->
name)
289 "ftruncate() \"%s\" failed", fm->name)if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "ftruncate() \"%s\" failed", fm->
name)
;
290 goto failed;
291 }
292
293 fm->addr = mmap(NULL((void*)0), fm->size, PROT_READ0x01|PROT_WRITE0x02, MAP_SHARED0x0001,
294 fm->fd, 0);
295 if (fm->addr != MAP_FAILED((void *)-1)) {
296 return NGX_OK0;
297 }
298
299 ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "mmap(%uz) \"%s\" failed", fm->
size, fm->name)
300 "mmap(%uz) \"%s\" failed", fm->size, fm->name)if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "mmap(%uz) \"%s\" failed", fm->
size, fm->name)
;
301
302failed:
303
304 if (ngx_close_fileclose(fm->fd) == NGX_FILE_ERROR-1) {
305 ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,if ((fm->log)->log_level >= 2) ngx_log_error_core(2,
fm->log, (*__error()), "close()" " \"%s\" failed", fm->
name)
306 ngx_close_file_n " \"%s\" failed", fm->name)if ((fm->log)->log_level >= 2) ngx_log_error_core(2,
fm->log, (*__error()), "close()" " \"%s\" failed", fm->
name)
;
307 }
308
309 return NGX_ERROR-1;
310}
311
312
313void
314ngx_close_file_mapping(ngx_file_mapping_t *fm)
315{
316 if (munmap(fm->addr, fm->size) == -1) {
317 ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "munmap(%uz) \"%s\" failed", fm->
size, fm->name)
318 "munmap(%uz) \"%s\" failed", fm->size, fm->name)if ((fm->log)->log_level >= 3) ngx_log_error_core(3,
fm->log, (*__error()), "munmap(%uz) \"%s\" failed", fm->
size, fm->name)
;
319 }
320
321 if (ngx_close_fileclose(fm->fd) == NGX_FILE_ERROR-1) {
322 ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,if ((fm->log)->log_level >= 2) ngx_log_error_core(2,
fm->log, (*__error()), "close()" " \"%s\" failed", fm->
name)
323 ngx_close_file_n " \"%s\" failed", fm->name)if ((fm->log)->log_level >= 2) ngx_log_error_core(2,
fm->log, (*__error()), "close()" " \"%s\" failed", fm->
name)
;
324 }
325}
326
327
328ngx_int_t
329ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
330{
331 dir->dir = opendir((const char *) name->data);
332
333 if (dir->dir == NULL((void*)0)) {
334 return NGX_ERROR-1;
335 }
336
337 dir->valid_info = 0;
338
339 return NGX_OK0;
340}
341
342
343ngx_int_t
344ngx_read_dir(ngx_dir_t *dir)
345{
346 dir->de = readdir(dir->dir);
347
348 if (dir->de) {
349#if (NGX_HAVE_D_TYPE1)
350 dir->type = dir->de->d_type;
351#else
352 dir->type = 0;
353#endif
354 return NGX_OK0;
355 }
356
357 return NGX_ERROR-1;
358}
359
360
361ngx_int_t
362ngx_open_glob(ngx_glob_t *gl)
363{
364 int n;
365
366 n = glob((char *) gl->pattern, 0, NULL((void*)0), &gl->pglob);
367
368 if (n == 0) {
369 return NGX_OK0;
370 }
371
372#ifdef GLOB_NOMATCH(-3)
373
374 if (n == GLOB_NOMATCH(-3) && gl->test) {
375 return NGX_OK0;
376 }
377
378#endif
379
380 return NGX_ERROR-1;
381}
382
383
384ngx_int_t
385ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
386{
387 size_t count;
388
389#ifdef GLOB_NOMATCH(-3)
390 count = (size_t) gl->pglob.gl_pathc;
391#else
392 count = (size_t) gl->pglob.gl_matchc;
393#endif
394
395 if (gl->n < count) {
396
397 name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n])strlen((const char *) gl->pglob.gl_pathv[gl->n]);
398 name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
399 gl->n++;
400
401 return NGX_OK0;
402 }
403
404 return NGX_DONE-4;
405}
406
407
408void
409ngx_close_glob(ngx_glob_t *gl)
410{
411 globfree(&gl->pglob);
412}
413
414
415ngx_err_t
416ngx_trylock_fd(ngx_fd_t fd)
417{
418 struct flock fl;
419
420 ngx_memzero(&fl, sizeof(struct flock))(void) ((__builtin_object_size (&fl, 0) != (size_t) -1) ?
__builtin___memset_chk (&fl, 0, sizeof(struct flock), __builtin_object_size
(&fl, 0)) : __inline_memset_chk (&fl, 0, sizeof(struct
flock)))
;
421 fl.l_type = F_WRLCK3;
422 fl.l_whence = SEEK_SET0;
423
424 if (fcntl(fd, F_SETLK8, &fl) == -1) {
425 return ngx_errno(*__error());
426 }
427
428 return 0;
429}
430
431
432ngx_err_t
433ngx_lock_fd(ngx_fd_t fd)
434{
435 struct flock fl;
436
437 ngx_memzero(&fl, sizeof(struct flock))(void) ((__builtin_object_size (&fl, 0) != (size_t) -1) ?
__builtin___memset_chk (&fl, 0, sizeof(struct flock), __builtin_object_size
(&fl, 0)) : __inline_memset_chk (&fl, 0, sizeof(struct
flock)))
;
438 fl.l_type = F_WRLCK3;
439 fl.l_whence = SEEK_SET0;
440
441 if (fcntl(fd, F_SETLKW9, &fl) == -1) {
442 return ngx_errno(*__error());
443 }
444
445 return 0;
446}
447
448
449ngx_err_t
450ngx_unlock_fd(ngx_fd_t fd)
451{
452 struct flock fl;
453
454 ngx_memzero(&fl, sizeof(struct flock))(void) ((__builtin_object_size (&fl, 0) != (size_t) -1) ?
__builtin___memset_chk (&fl, 0, sizeof(struct flock), __builtin_object_size
(&fl, 0)) : __inline_memset_chk (&fl, 0, sizeof(struct
flock)))
;
455 fl.l_type = F_UNLCK2;
456 fl.l_whence = SEEK_SET0;
457
458 if (fcntl(fd, F_SETLK8, &fl) == -1) {
459 return ngx_errno(*__error());
460 }
461
462 return 0;
463}
464
465
466#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
467
468ngx_int_t
469ngx_read_ahead(ngx_fd_t fd, size_t n)0
470{
471 int err;
472
473 err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
474
475 if (err == 0) {
476 return 0;
477 }
478
479 ngx_set_errno(err)(*__error()) = err;
480 return NGX_FILE_ERROR-1;
481}
482
483#endif
484
485
486#if (NGX_HAVE_O_DIRECT)
487
488ngx_int_t
489ngx_directio_on(ngx_fd_t fd)fcntl(ngx_fd_t fd, 48, 1)
490{
491 int flags;
492
493 flags = fcntl(fd, F_GETFL3);
494
495 if (flags == -1) {
496 return NGX_FILE_ERROR-1;
497 }
498
499 return fcntl(fd, F_SETFL4, flags | O_DIRECT);
500}
501
502
503ngx_int_t
504ngx_directio_off(ngx_fd_t fd)
505{
506 int flags;
507
508 flags = fcntl(fd, F_GETFL3);
509
510 if (flags == -1) {
511 return NGX_FILE_ERROR-1;
512 }
513
514 return fcntl(fd, F_SETFL4, flags & ~O_DIRECT);
515}
516
517#endif
518
519
520#if (NGX_HAVE_STATFS1)
521
522size_t
523ngx_fs_bsize(u_char *name)
524{
525 struct statfs fs;
526
527 if (statfs((char *) name, &fs) == -1) {
528 return 512;
529 }
530
531 if ((fs.f_bsize % 512) != 0) {
532 return 512;
533 }
534
535 return (size_t) fs.f_bsize;
536}
537
538#elif (NGX_HAVE_STATVFS1)
539
540size_t
541ngx_fs_bsize(u_char *name)
542{
543 struct statvfs fs;
544
545 if (statvfs((char *) name, &fs) == -1) {
546 return 512;
547 }
548
549 if ((fs.f_frsize % 512) != 0) {
550 return 512;
551 }
552
553 return (size_t) fs.f_frsize;
554}
555
556#else
557
558size_t
559ngx_fs_bsize(u_char *name)
560{
561 return 512;
562}
563
564#endif