Move safe alloc routines into common lib file.
[platform/upstream/cryptsetup.git] / lib / utils.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stddef.h>
5 #include <stdarg.h>
6 #include <errno.h>
7 #include <linux/fs.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <sys/ioctl.h>
13 #include <fcntl.h>
14 #include <termios.h>
15 #include <sys/mman.h>
16 #include <sys/resource.h>
17
18 #include "libcryptsetup.h"
19 #include "internal.h"
20
21 static char *error=NULL;
22
23 void set_error_va(const char *fmt, va_list va)
24 {
25         int r;
26
27         if(error) {
28                 free(error);
29                 error = NULL;
30         }
31
32         if(!fmt) return;
33
34         r = vasprintf(&error, fmt, va);
35         if (r < 0) {
36                 free(error);
37                 error = NULL;
38                 return;
39         }
40
41         if (r && error[r - 1] == '\n')
42                 error[r - 1] = '\0';
43 }
44
45 void set_error(const char *fmt, ...)
46 {
47         va_list va;
48
49         va_start(va, fmt);
50         set_error_va(fmt, va);
51         va_end(va);
52 }
53
54 const char *get_error(void)
55 {
56         return error;
57 }
58
59 static int get_alignment(int fd)
60 {
61         int alignment = DEFAULT_MEM_ALIGNMENT;
62
63 #ifdef _PC_REC_XFER_ALIGN
64         alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
65         if (alignment < 0)
66                 alignment = DEFAULT_MEM_ALIGNMENT;
67 #endif
68         return alignment;
69 }
70
71 static void *aligned_malloc(void **base, int size, int alignment)
72 {
73 #ifdef HAVE_POSIX_MEMALIGN
74         return posix_memalign(base, alignment, size) ? NULL : *base;
75 #else
76 /* Credits go to Michal's padlock patches for this alignment code */
77         char *ptr;
78
79         ptr  = malloc(size + alignment);
80         if(ptr == NULL) return NULL;
81
82         *base = ptr;
83         if(alignment > 1 && ((long)ptr & (alignment - 1))) {
84                 ptr += alignment - ((long)(ptr) & (alignment - 1));
85         }
86         return ptr;
87 #endif
88 }
89 static int sector_size(int fd) 
90 {
91         int bsize;
92         if (ioctl(fd,BLKSSZGET, &bsize) < 0)
93                 return -EINVAL;
94         else
95                 return bsize;
96 }
97
98 int sector_size_for_device(const char *device)
99 {
100         int fd = open(device, O_RDONLY);
101         int r;
102         if(fd < 0)
103                 return -EINVAL;
104         r = sector_size(fd);
105         close(fd);
106         return r;
107 }
108
109 ssize_t write_blockwise(int fd, const void *orig_buf, size_t count)
110 {
111         void *hangover_buf, *hangover_buf_base = NULL;
112         void *buf, *buf_base = NULL;
113         int r, hangover, solid, bsize, alignment;
114         ssize_t ret = -1;
115
116         if ((bsize = sector_size(fd)) < 0)
117                 return bsize;
118
119         hangover = count % bsize;
120         solid = count - hangover;
121         alignment = get_alignment(fd);
122
123         if ((long)orig_buf & (alignment - 1)) {
124                 buf = aligned_malloc(&buf_base, count, alignment);
125                 if (!buf)
126                         goto out;
127                 memcpy(buf, orig_buf, count);
128         } else
129                 buf = (void *)orig_buf;
130
131         r = write(fd, buf, solid);
132         if (r < 0 || r != solid)
133                 goto out;
134
135         if (hangover) {
136                 hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
137                 if (!hangover_buf)
138                         goto out;
139
140                 r = read(fd, hangover_buf, bsize);
141                 if(r < 0 || r != bsize) goto out;
142
143                 r = lseek(fd, -bsize, SEEK_CUR);
144                 if (r < 0)
145                         goto out;
146                 memcpy(hangover_buf, buf + solid, hangover);
147
148                 r = write(fd, hangover_buf, bsize);
149                 if(r < 0 || r != bsize) goto out;
150                 free(hangover_buf_base);
151         }
152         ret = count;
153  out:
154         if (buf != orig_buf)
155                 free(buf_base);
156         return ret;
157 }
158
159 ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
160         void *hangover_buf, *hangover_buf_base;
161         void *buf, *buf_base = NULL;
162         int r, hangover, solid, bsize, alignment;
163         ssize_t ret = -1;
164
165         if ((bsize = sector_size(fd)) < 0)
166                 return bsize;
167
168         hangover = count % bsize;
169         solid = count - hangover;
170         alignment = get_alignment(fd);
171
172         if ((long)orig_buf & (alignment - 1)) {
173                 buf = aligned_malloc(&buf_base, count, alignment);
174                 if (!buf)
175                         goto out;
176         } else
177                 buf = orig_buf;
178
179         r = read(fd, buf, solid);
180         if(r < 0 || r != solid)
181                 goto out;
182
183         if (hangover) {
184                 hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
185                 if (!hangover_buf)
186                         goto out;
187                 r = read(fd, hangover_buf, bsize);
188                 if (r <  0 || r != bsize)
189                         goto out;
190
191                 memcpy(buf + solid, hangover_buf, hangover);
192                 free(hangover_buf_base);
193         }
194         ret = count;
195  out:
196         if (buf != orig_buf) {
197                 memcpy(orig_buf, buf, count);
198                 free(buf_base);
199         }
200         return ret;
201 }
202
203 /* 
204  * Combines llseek with blockwise write. write_blockwise can already deal with short writes
205  * but we also need a function to deal with short writes at the start. But this information
206  * is implicitly included in the read/write offset, which can not be set to non-aligned 
207  * boundaries. Hence, we combine llseek with write.
208  */
209
210 ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset) {
211         int bsize = sector_size(fd);
212         const char *orig_buf = buf;
213         char frontPadBuf[bsize];
214         int frontHang = offset % bsize;
215         int r;
216         int innerCount = count < bsize ? count : bsize;
217
218         if (bsize < 0)
219                 return bsize;
220
221         lseek(fd, offset - frontHang, SEEK_SET);
222         if(offset % bsize) {
223                 r = read(fd,frontPadBuf,bsize);
224                 if(r < 0) return -1;
225
226                 memcpy(frontPadBuf+frontHang, buf, innerCount);
227
228                 lseek(fd, offset - frontHang, SEEK_SET);
229                 r = write(fd,frontPadBuf,bsize);
230                 if(r < 0) return -1;
231
232                 buf += innerCount;
233                 count -= innerCount;
234         }
235         if(count <= 0) return buf - orig_buf;
236
237         return write_blockwise(fd, buf, count) + innerCount;
238 }
239
240 /* Password reading helpers */
241
242 static int untimed_read(int fd, char *pass, size_t maxlen)
243 {
244         ssize_t i;
245
246         i = read(fd, pass, maxlen);
247         if (i > 0) {
248                 pass[i-1] = '\0';
249                 i = 0;
250         } else if (i == 0) { /* EOF */
251                 *pass = 0;
252                 i = -1;
253         }
254         return i;
255 }
256
257 static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
258 {
259         struct timeval t;
260         fd_set fds;
261         int failed = -1;
262
263         FD_ZERO(&fds);
264         FD_SET(fd, &fds);
265         t.tv_sec = timeout;
266         t.tv_usec = 0;
267
268         if (select(fd+1, &fds, NULL, NULL, &t) > 0)
269                 failed = untimed_read(fd, pass, maxlen);
270
271         return failed;
272 }
273
274 static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
275                 long timeout)
276 {
277         struct termios orig, tmp;
278         int failed = -1;
279         int infd = STDIN_FILENO, outfd;
280
281         if (maxlen < 1)
282                 goto out_err;
283
284         /* Read and write to /dev/tty if available */
285         if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
286                 infd = STDIN_FILENO;
287                 outfd = STDERR_FILENO;
288         }
289
290         if (tcgetattr(infd, &orig))
291                 goto out_err;
292
293         memcpy(&tmp, &orig, sizeof(tmp));
294         tmp.c_lflag &= ~ECHO;
295
296         if (write(outfd, prompt, strlen(prompt)) < 0)
297                 goto out_err;
298
299         tcsetattr(infd, TCSAFLUSH, &tmp);
300         if (timeout)
301                 failed = timed_read(infd, pass, maxlen, timeout);
302         else
303                 failed = untimed_read(infd, pass, maxlen);
304         tcsetattr(infd, TCSAFLUSH, &orig);
305
306 out_err:
307         if (!failed && write(outfd, "\n", 1));
308
309         if (infd != STDIN_FILENO)
310                 close(infd);
311         return failed;
312 }
313
314 /*
315  * Password reading behaviour matrix of get_key
316  * FIXME: rewrite this from scratch.
317  *                    p   v   n   h
318  * -----------------+---+---+---+---
319  * interactive      | Y | Y | Y | Inf
320  * from fd          | N | N | Y | Inf
321  * from binary file | N | N | N | Inf or options->key_size
322  *
323  * Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
324  *
325  * Note: --key-file=- is interpreted as a read from a binary file (stdin)
326  */
327
328 void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
329             const char *key_file, int timeout, int how2verify,
330             struct crypt_device *cd)
331 {
332         int fd = -1;
333         const int verify = how2verify & CRYPT_FLAG_VERIFY;
334         const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
335         char *pass = NULL;
336         int read_horizon;
337         int regular_file = 0;
338         int read_stdin;
339         int r;
340         struct stat st;
341
342         /* Passphrase read from stdin? */
343         read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0;
344
345         /* read_horizon applies only for real keyfile, not stdin or terminal */
346         read_horizon = (key_file && !read_stdin) ? key_size : 0 /* until EOF */;
347
348         /* Setup file descriptior */
349         fd = read_stdin ? STDIN_FILENO : open(key_file, O_RDONLY);
350         if (fd < 0) {
351                 log_err(cd, _("Failed to open key file %s.\n"), key_file ?: "-");
352                 goto out_err;
353         }
354
355         /* Interactive case */
356         if(isatty(fd)) {
357                 int i;
358
359                 pass = crypt_safe_alloc(MAX_TTY_PASSWORD_LEN);
360                 if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) {
361                         log_err(cd, _("Error reading passphrase from terminal.\n"));
362                         goto out_err;
363                 }
364                 if (verify || verify_if_possible) {
365                         char pass_verify[MAX_TTY_PASSWORD_LEN];
366                         i = interactive_pass(_("Verify passphrase: "), pass_verify, sizeof(pass_verify), timeout);
367                         if (i || strcmp(pass, pass_verify) != 0) {
368                                 log_err(cd, _("Passphrases do not match.\n"));
369                                 goto out_err;
370                         }
371                         memset(pass_verify, 0, sizeof(pass_verify));
372                 }
373                 *passLen = strlen(pass);
374                 *key = pass;
375         } else {
376                 /* 
377                  * This is either a fd-input or a file, in neither case we can verify the input,
378                  * however we don't stop on new lines if it's a binary file.
379                  */
380                 int buflen, i;
381
382                 if(verify) {
383                         log_err(cd, _("Can't do passphrase verification on non-tty inputs.\n"));
384                         goto out_err;
385                 }
386                 /* The following for control loop does an exhausting
387                  * read on the key material file, if requested with
388                  * key_size == 0, as it's done by LUKS. However, we
389                  * should warn the user, if it's a non-regular file,
390                  * such as /dev/random, because in this case, the loop
391                  * will read forever.
392                  */
393                 if(!read_stdin && read_horizon == 0) {
394                         if(stat(key_file, &st) < 0) {
395                                 log_err(cd, _("Failed to stat key file %s.\n"), key_file);
396                                 goto out_err;
397                         }
398                         if(!S_ISREG(st.st_mode))
399                                 log_std(cd, _("Warning: exhausting read requested, but key file %s"
400                                         " is not a regular file, function might never return.\n"),
401                                         key_file);
402                         else
403                                 regular_file = 1;
404                 }
405                 buflen = 0;
406                 for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
407                         if(i >= buflen - 1) {
408                                 buflen += 128;
409                                 pass = crypt_safe_realloc(pass, buflen);
410                                 if (!pass) {
411                                         log_err(cd, _("Out of memory while reading passphrase.\n"));
412                                         goto out_err;
413                                 }
414                         }
415
416                         r = read(fd, pass + i, 1);
417                         if (r < 0) {
418                                 log_err(cd, _("Error reading passphrase.\n"));
419                                 goto out_err;
420                         }
421
422                         /* Stop on newline only if not requested read from keyfile */
423                         if(r == 0 || (!key_file && pass[i] == '\n'))
424                                 break;
425                 }
426                 /* Fail if piped input dies reading nothing */
427                 if(!i && !regular_file) {
428                         log_dbg("Error reading passphrase.");
429                         goto out_err;
430                 }
431                 pass[i] = 0;
432                 *key = pass;
433                 *passLen = i;
434         }
435         if(fd != STDIN_FILENO)
436                 close(fd);
437         return;
438
439 out_err:
440         if(fd >= 0 && fd != STDIN_FILENO)
441                 close(fd);
442         if(pass)
443                 crypt_safe_free(pass);
444         *key = NULL;
445         *passLen = 0;
446 }
447
448 int device_ready(struct crypt_device *cd, const char *device, int mode)
449 {
450         int devfd, r = 1;
451         ssize_t s;
452         struct stat st;
453         char buf[512];
454
455         if(stat(device, &st) < 0) {
456                 log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
457                 return 0;
458         }
459
460         log_dbg("Trying to open and read device %s.", device);
461         devfd = open(device, mode | O_DIRECT | O_SYNC);
462         if(devfd < 0) {
463                 log_err(cd, _("Cannot open device %s for %s%s access.\n"), device,
464                         (mode & O_EXCL) ? _("exclusive ") : "",
465                         (mode & O_RDWR) ? _("writable") : _("read-only"));
466                 return 0;
467         }
468
469          /* Try to read first sector */
470         s = read_blockwise(devfd, buf, sizeof(buf));
471         if (s < 0 || s != sizeof(buf)) {
472                 log_err(cd, _("Cannot read device %s.\n"), device);
473                 r = 0;
474         }
475
476         memset(buf, 0, sizeof(buf));
477         close(devfd);
478
479         return r;
480 }
481
482 int get_device_infos(const char *device, struct device_infos *infos, struct crypt_device *cd)
483 {
484         uint64_t size;
485         unsigned long size_small;
486         int readonly = 0;
487         int ret = -1;
488         int fd;
489
490         /* Try to open read-write to check whether it is a read-only device */
491         fd = open(device, O_RDWR);
492         if (fd < 0) {
493                 if (errno == EROFS) {
494                         readonly = 1;
495                         fd = open(device, O_RDONLY);
496                 }
497         } else {
498                 close(fd);
499                 fd = open(device, O_RDONLY);
500         }
501         if (fd < 0) {
502                 log_err(cd, _("Cannot open device: %s\n"), device);
503                 return -1;
504         }
505
506 #ifdef BLKROGET
507         /* If the device can be opened read-write, i.e. readonly is still 0, then
508          * check whether BKROGET says that it is read-only. E.g. read-only loop
509          * devices may be openend read-write but are read-only according to BLKROGET
510          */
511         if (readonly == 0 && ioctl(fd, BLKROGET, &readonly) < 0) {
512                 log_err(cd, _("BLKROGET failed on device %s.\n"), device);
513                 goto out;
514         }
515 #else
516 #error BLKROGET not available
517 #endif
518
519 #ifdef BLKGETSIZE64
520         if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
521                 size >>= SECTOR_SHIFT;
522                 ret = 0;
523                 goto out;
524         }
525 #endif
526
527 #ifdef BLKGETSIZE
528         if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
529                 size = (uint64_t)size_small;
530                 ret = 0;
531                 goto out;
532         }
533 #else
534 #       error Need at least the BLKGETSIZE ioctl!
535 #endif
536
537         log_err(cd, _("BLKGETSIZE failed on device %s.\n"), device);
538 out:
539         if (ret == 0) {
540                 infos->size = size;
541                 infos->readonly = readonly;
542         }
543         close(fd);
544         return ret;
545 }
546
547 int wipe_device_header(const char *device, int sectors)
548 {
549         char *buffer;
550         int size = sectors * SECTOR_SIZE;
551         int r = -1;
552         int devfd;
553
554         devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
555         if(devfd == -1)
556                 return -EINVAL;
557
558         buffer = malloc(size);
559         if (!buffer) {
560                 close(devfd);
561                 return -ENOMEM;
562         }
563         memset(buffer, 0, size);
564
565         r = write_blockwise(devfd, buffer, size) < size ? -EIO : 0;
566
567         free(buffer);
568         close(devfd);
569
570         return r;
571 }
572
573 /* MEMLOCK */
574 #define DEFAULT_PROCESS_PRIORITY -18
575
576 static int _priority;
577 static int _memlock_count = 0;
578
579 // return 1 if memory is locked
580 int crypt_memlock_inc(struct crypt_device *ctx)
581 {
582         if (!_memlock_count++) {
583                 log_dbg("Locking memory.");
584                 if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
585                         log_err(ctx, _("WARNING!!! Possibly insecure memory. Are you root?\n"));
586                         _memlock_count--;
587                         return 0;
588                 }
589                 errno = 0;
590                 if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
591                         log_err(ctx, _("Cannot get process priority.\n"));
592                 else
593                         if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
594                                 log_err(ctx, _("setpriority %u failed: %s"),
595                                         DEFAULT_PROCESS_PRIORITY, strerror(errno));
596         }
597         return _memlock_count ? 1 : 0;
598 }
599
600 int crypt_memlock_dec(struct crypt_device *ctx)
601 {
602         if (_memlock_count && (!--_memlock_count)) {
603                 log_dbg("Unlocking memory.");
604                 if (munlockall())
605                         log_err(ctx, _("Cannot unlock memory."));
606                 if (setpriority(PRIO_PROCESS, 0, _priority))
607                         log_err(ctx, _("setpriority %u failed: %s"), _priority, strerror(errno));
608         }
609         return _memlock_count ? 1 : 0;
610 }
611
612 /* DEVICE TOPOLOGY */
613
614 /* block device topology ioctls, introduced in 2.6.32 */
615 #ifndef BLKIOMIN
616 #define BLKIOMIN    _IO(0x12,120)
617 #define BLKIOOPT    _IO(0x12,121)
618 #define BLKALIGNOFF _IO(0x12,122)
619 #endif
620
621 void get_topology_alignment(const char *device,
622                             unsigned long *required_alignment, /* bytes */
623                             unsigned long *alignment_offset,   /* bytes */
624                             unsigned long default_alignment)
625 {
626         int dev_alignment_offset = 0;
627         unsigned int min_io_size = 0, opt_io_size = 0;
628         unsigned long temp_alignment = 0;
629         int fd;
630
631         *required_alignment = default_alignment;
632         *alignment_offset = 0;
633
634         fd = open(device, O_RDONLY);
635         if (fd == -1)
636                 return;
637
638         /* minimum io size */
639         if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
640                 log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
641                         device, default_alignment);
642                 goto out;
643         }
644
645         /* optimal io size */
646         if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
647                 opt_io_size = min_io_size;
648
649         /* alignment offset, bogus -1 means misaligned/unknown */
650         if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
651                 dev_alignment_offset = 0;
652         *alignment_offset = (unsigned long)dev_alignment_offset;
653
654         temp_alignment = (unsigned long)min_io_size;
655
656         if (temp_alignment < (unsigned long)opt_io_size)
657                 temp_alignment = (unsigned long)opt_io_size;
658
659         /* If calculated alignment is multiple of default, keep default */
660         if (temp_alignment && (default_alignment % temp_alignment))
661                 *required_alignment = temp_alignment;
662
663         log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
664                 min_io_size, opt_io_size, *alignment_offset, *required_alignment);
665 out:
666         (void)close(fd);
667 }