extattr.c
1 /*- 2 * Copyright (c) 2020 Shawn Webb <shawn.webb@hardenedbsd.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer 9 * in this position and unchanged. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 27 #include <archive.h> 28 #include <archive_entry.h> 29 #include <assert.h> 30 #include <fcntl.h> 31 #include <fts.h> 32 #include <string.h> 33 #include <pwd.h> 34 #include <grp.h> 35 #include <errno.h> 36 37 #include <sys/types.h> 38 #include <sys/extattr.h> 39 40 #include "pkg.h" 41 #include "private/event.h" 42 #include "private/pkg.h" 43 44 int 45 pkg_archive_extattrs(int fd, struct archive_entry *entry) 46 { 47 const char *nameprefix = "system."; 48 char *endp, *name, *names, *namep; 49 ssize_t datasize, listsize; 50 int err, namespace; 51 uint8_t namesize; 52 void *attrdata; 53 54 err = EPKG_OK; 55 attrdata = NULL; 56 names = NULL; 57 58 namespace = EXTATTR_NAMESPACE_SYSTEM; 59 60 listsize = extattr_list_fd(fd, namespace, NULL, 0); 61 if (listsize < 0) { 62 return (EPKG_OK); 63 } 64 65 if (listsize == 0) { 66 return (EPKG_OK); 67 } 68 69 names = calloc(listsize, 1); 70 if (names == NULL) { 71 return (EPKG_OK); 72 } 73 74 if (extattr_list_fd(fd, namespace, names, listsize) != 75 listsize) { 76 goto end; 77 } 78 endp = names + (size_t)listsize; 79 for (namep = names; namep < endp; namep += namesize) { 80 namesize = *((uint8_t *)(namep)); 81 name = calloc(strlen(nameprefix) + namesize+1, 1); 82 if (name == NULL) { 83 goto end; 84 } 85 namep += sizeof(uint8_t); 86 strcpy(name, nameprefix); 87 strncat(name, namep, namesize); 88 89 datasize = extattr_get_fd(fd, namespace, name+strlen(nameprefix), NULL, 0); 90 if (datasize < 0) { 91 free(name); 92 continue; 93 } 94 95 attrdata = calloc(1, (size_t)datasize); 96 if (attrdata == NULL) { 97 free(name); 98 goto end; 99 } 100 101 if (extattr_get_fd(fd, namespace, name+strlen(nameprefix), attrdata, 102 datasize) != datasize) { 103 perror("extattr_get_fd"); 104 free(name); 105 free(attrdata); 106 goto end; 107 } 108 109 archive_entry_xattr_add_entry(entry, name, attrdata, 110 datasize); 111 112 free(name); 113 free(attrdata); 114 } 115 116 end: 117 free(names); 118 return (EPKG_OK); 119 }