Browse Source

musl: added getent utility from alpine linux and a hotfix from upstream.

master
Nagy Károly Gábriel 9 years ago
parent
commit
7f21f5e33d
3 changed files with 507 additions and 0 deletions
  1. +48
    -0
      base/musl/fix-single-byte-overflow.patch
  2. +453
    -0
      base/musl/getent.c
  3. +6
    -0
      base/musl/musl.conf

+ 48
- 0
base/musl/fix-single-byte-overflow.patch

@ -0,0 +1,48 @@
# --- SDE-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
#
# Filename: package/.../musl/fix-single-byte-overflow.patch
# Copyright (C) 2015 The OpenSDE Project
#
# More information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- SDE-COPYRIGHT-NOTE-END ---
From b114190b29417fff6f701eea3a3b3b6030338280 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sat, 24 Oct 2015 22:42:10 -0400
Subject: fix single-byte overflow of malloc'd buffer in getdelim
the buffer enlargement logic here accounted for the terminating null
byte, but not for the possibility of hitting the delimiter in the
buffer-refill code path that uses getc_unlocked, in which case two
additional bytes (the delimiter and the null termination) are written
without another chance to enlarge the buffer.
this patch and the corresponding bug report are by Felix Janda.
---
src/stdio/getdelim.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c
index a88c393..3077490 100644
--- a/src/stdio/getdelim.c
+++ b/src/stdio/getdelim.c
@@ -27,7 +27,7 @@ ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restric
for (;;) {
z = memchr(f->rpos, delim, f->rend - f->rpos);
k = z ? z - f->rpos + 1 : f->rend - f->rpos;
- if (i+k >= *n) {
+ if (i+k+1 >= *n) {
if (k >= SIZE_MAX/2-i) goto oom;
*n = i+k+2;
if (*n < SIZE_MAX/4) *n *= 2;
--
cgit v0.11.2

+ 453
- 0
base/musl/getent.c

@ -0,0 +1,453 @@
/*
* --- SDE-COPYRIGHT-NOTE-BEGIN ---
* This copyright note is auto-generated by ./scripts/Create-CopyPatch.
*
* Filename: package/.../musl/getent.c
* Copyright (C) 2015 The OpenSDE Project
*
* More information can be found in the files COPYING and README.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License. A copy of the
* GNU General Public License can be found in the file COPYING.
* --- SDE-COPYRIGHT-NOTE-END ---
*/
/*-
* Copyright (c) 2004-2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
* Timo Teräs cleaned up the code for use in Alpine Linux with musl libc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <netdb.h>
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <paths.h>
#include <err.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/in.h>
enum {
RV_OK = 0,
RV_USAGE = 1,
RV_NOTFOUND = 2,
RV_NOENUM = 3
};
static int usage(const char *);
static int parsenum(const char *word, unsigned long *result)
{
unsigned long num;
char *ep;
if (!isdigit((unsigned char)word[0]))
return 0;
errno = 0;
num = strtoul(word, &ep, 10);
if (num == ULONG_MAX && errno == ERANGE)
return 0;
if (*ep != '\0')
return 0;
*result = num;
return 1;
}
/*
* printfmtstrings --
* vprintf(format, ...),
* then the aliases (beginning with prefix, separated by sep),
* then a newline
*/
__attribute__ ((format (printf, 4, 5)))
static void printfmtstrings(char *strings[], const char *prefix, const char *sep,
const char *fmt, ...)
{
va_list ap;
const char *curpref;
size_t i;
va_start(ap, fmt);
(void)vprintf(fmt, ap);
va_end(ap);
curpref = prefix;
for (i = 0; strings[i] != NULL; i++) {
(void)printf("%s%s", curpref, strings[i]);
curpref = sep;
}
(void)printf("\n");
}
static int ethers(int argc, char *argv[])
{
char hostname[MAXHOSTNAMELEN + 1], *hp;
struct ether_addr ea, *eap;
int i, rv;
if (argc == 2) {
warnx("Enumeration not supported on ethers");
return RV_NOENUM;
}
rv = RV_OK;
for (i = 2; i < argc; i++) {
if ((eap = ether_aton(argv[i])) == NULL) {
eap = &ea;
hp = argv[i];
if (ether_hostton(hp, eap) != 0) {
rv = RV_NOTFOUND;
break;
}
} else {
hp = hostname;
if (ether_ntohost(hp, eap) != 0) {
rv = RV_NOTFOUND;
break;
}
}
(void)printf("%-17s %s\n", ether_ntoa(eap), hp);
}
return rv;
}
static void groupprint(const struct group *gr)
{
printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u",
gr->gr_name, gr->gr_passwd, gr->gr_gid);
}
static int group(int argc, char *argv[])
{
struct group *gr;
unsigned long id;
int i, rv;
rv = RV_OK;
if (argc == 2) {
while ((gr = getgrent()) != NULL)
groupprint(gr);
} else {
for (i = 2; i < argc; i++) {
if (parsenum(argv[i], &id))
gr = getgrgid((gid_t)id);
else
gr = getgrnam(argv[i]);
if (gr == NULL) {
rv = RV_NOTFOUND;
break;
}
groupprint(gr);
}
}
endgrent();
return rv;
}
static void hostsprint(const struct hostent *he)
{
char buf[INET6_ADDRSTRLEN];
if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL)
(void)strlcpy(buf, "# unknown", sizeof(buf));
printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name);
}
static int hosts(int argc, char *argv[])
{
struct hostent *he;
char addr[IN6ADDRSZ];
int i, rv;
sethostent(1);
rv = RV_OK;
if (argc == 2) {
while ((he = gethostent()) != NULL)
hostsprint(he);
} else {
for (i = 2; i < argc; i++) {
if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, INADDRSZ, AF_INET);
else
he = gethostbyname(argv[i]);
if (he == NULL) {
rv = RV_NOTFOUND;
break;
}
hostsprint(he);
}
}
endhostent();
return rv;
}
static void networksprint(const struct netent *ne)
{
char buf[INET6_ADDRSTRLEN];
struct in_addr ianet;
ianet = inet_makeaddr(ne->n_net, 0);
if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL)
(void)strlcpy(buf, "# unknown", sizeof(buf));
printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf);
}
static int networks(int argc, char *argv[])
{
struct netent *ne;
in_addr_t net;
int i, rv;
setnetent(1);
rv = RV_OK;
if (argc == 2) {
while ((ne = getnetent()) != NULL)
networksprint(ne);
} else {
for (i = 2; i < argc; i++) {
net = inet_network(argv[i]);
if (net != INADDR_NONE)
ne = getnetbyaddr(net, AF_INET);
else
ne = getnetbyname(argv[i]);
if (ne != NULL) {
rv = RV_NOTFOUND;
break;
}
networksprint(ne);
}
}
endnetent();
return rv;
}
static void passwdprint(struct passwd *pw)
{
(void)printf("%s:%s:%u:%u:%s:%s:%s\n",
pw->pw_name, pw->pw_passwd, pw->pw_uid,
pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell);
}
static int passwd(int argc, char *argv[])
{
struct passwd *pw;
unsigned long id;
int i, rv;
rv = RV_OK;
if (argc == 2) {
while ((pw = getpwent()) != NULL)
passwdprint(pw);
} else {
for (i = 2; i < argc; i++) {
if (parsenum(argv[i], &id))
pw = getpwuid((uid_t)id);
else
pw = getpwnam(argv[i]);
if (pw == NULL) {
rv = RV_NOTFOUND;
break;
}
passwdprint(pw);
}
}
endpwent();
return rv;
}
static void protocolsprint(struct protoent *pe)
{
printfmtstrings(pe->p_aliases, " ", " ",
"%-16s %5d", pe->p_name, pe->p_proto);
}
static int protocols(int argc, char *argv[])
{
struct protoent *pe;
unsigned long id;
int i, rv;
setprotoent(1);
rv = RV_OK;
if (argc == 2) {
while ((pe = getprotoent()) != NULL)
protocolsprint(pe);
} else {
for (i = 2; i < argc; i++) {
if (parsenum(argv[i], &id))
pe = getprotobynumber((int)id);
else
pe = getprotobyname(argv[i]);
if (pe == NULL) {
rv = RV_NOTFOUND;
break;
}
protocolsprint(pe);
}
}
endprotoent();
return rv;
}
static void servicesprint(struct servent *se)
{
printfmtstrings(se->s_aliases, " ", " ",
"%-16s %5d/%s",
se->s_name, ntohs(se->s_port), se->s_proto);
}
static int services(int argc, char *argv[])
{
struct servent *se;
unsigned long id;
char *proto;
int i, rv;
setservent(1);
rv = RV_OK;
if (argc == 2) {
while ((se = getservent()) != NULL)
servicesprint(se);
} else {
for (i = 2; i < argc; i++) {
proto = strchr(argv[i], '/');
if (proto != NULL)
*proto++ = '\0';
if (parsenum(argv[i], &id))
se = getservbyport(htons(id), proto);
else
se = getservbyname(argv[i], proto);
if (se == NULL) {
rv = RV_NOTFOUND;
break;
}
servicesprint(se);
}
}
endservent();
return rv;
}
static int shells(int argc, char *argv[])
{
const char *sh;
int i, rv;
setusershell();
rv = RV_OK;
if (argc == 2) {
while ((sh = getusershell()) != NULL)
(void)printf("%s\n", sh);
} else {
for (i = 2; i < argc; i++) {
setusershell();
while ((sh = getusershell()) != NULL) {
if (strcmp(sh, argv[i]) == 0) {
(void)printf("%s\n", sh);
break;
}
}
if (sh == NULL) {
rv = RV_NOTFOUND;
break;
}
}
}
endusershell();
return rv;
}
static struct getentdb {
const char *name;
int (*callback)(int, char *[]);
} databases[] = {
{ "ethers", ethers, },
{ "group", group, },
{ "hosts", hosts, },
{ "networks", networks, },
{ "passwd", passwd, },
{ "protocols", protocols, },
{ "services", services, },
{ "shells", shells, },
{ NULL, NULL, },
};
static int usage(const char *arg0)
{
struct getentdb *curdb;
size_t i;
(void)fprintf(stderr, "Usage: %s database [key ...]\n", arg0);
(void)fprintf(stderr, "\tdatabase may be one of:");
for (i = 0, curdb = databases; curdb->name != NULL; curdb++, i++) {
if (i % 7 == 0)
(void)fputs("\n\t\t", stderr);
(void)fprintf(stderr, "%s%s", i % 7 == 0 ? "" : " ",
curdb->name);
}
(void)fprintf(stderr, "\n");
exit(RV_USAGE);
/* NOTREACHED */
}
int
main(int argc, char *argv[])
{
struct getentdb *curdb;
if (argc < 2)
usage(argv[0]);
for (curdb = databases; curdb->name != NULL; curdb++)
if (strcmp(curdb->name, argv[1]) == 0)
return (*curdb->callback)(argc, argv);
warn("Unknown database `%s'", argv[1]);
usage(argv[0]);
/* NOTREACHED */
}

+ 6
- 0
base/musl/musl.conf

@ -46,6 +46,11 @@ musl_postinstall() {
$root$bindir/ldd
}
musl_make_utils() {
# getent is needed by OpenSDE framework.
$CC $CPPFLAGS $CFLAGS $confdir/getent.c -o $root/$sbindir/getent
}
# if musl is default libc
if [ "$SDECFG_LIBC" == "musl" ]; then
# disable gcc wrapper script
@ -55,6 +60,7 @@ if [ "$SDECFG_LIBC" == "musl" ]; then
hook_add postinstall 5 'musl_postinstall'
fi
hook_add postflist 9 "rm -rf $root/$includedir/libintl.h"
hook_add postmake 5 'musl_make_utils'
fi
# always install the headers even if already present in the sandbox

Loading…
Cancel
Save