[Sanitizers] intercept ttyent api on FreeBSD.

and ttyentpath separately on NetBSD.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D109843
This commit is contained in:
David Carlier 2021-09-24 04:26:05 +01:00
parent 40ddde5d1f
commit 3675e147a1
6 changed files with 87 additions and 76 deletions

View File

@ -7543,6 +7543,14 @@ INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
return ttyent;
}
#define INIT_TTYENT \
COMMON_INTERCEPT_FUNCTION(getttyent); \
COMMON_INTERCEPT_FUNCTION(getttynam);
#else
#define INIT_TTYENT
#endif
#if SANITIZER_INTERCEPT_TTYENTPATH
INTERCEPTOR(int, setttyentpath, char *path) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
@ -7550,12 +7558,9 @@ INTERCEPTOR(int, setttyentpath, char *path) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
return REAL(setttyentpath)(path);
}
#define INIT_TTYENT \
COMMON_INTERCEPT_FUNCTION(getttyent); \
COMMON_INTERCEPT_FUNCTION(getttynam); \
COMMON_INTERCEPT_FUNCTION(setttyentpath)
#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);
#else
#define INIT_TTYENT
#define INIT_TTYENTPATH
#endif
#if SANITIZER_INTERCEPT_PROTOENT

View File

@ -521,7 +521,8 @@
#define SANITIZER_INTERCEPT_DEVNAME_R (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_TTYENT SI_NETBSD
#define SANITIZER_INTERCEPT_TTYENT (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_TTYENTPATH SI_NETBSD
#define SANITIZER_INTERCEPT_PROTOENT (SI_LINUX || SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC
#define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD)

View File

@ -74,6 +74,7 @@
#include <term.h>
#include <termios.h>
#include <time.h>
#include <ttyent.h>
#include <utime.h>
#include <utmpx.h>
#include <vis.h>
@ -174,6 +175,8 @@ const int wordexp_wrde_dooffs = WRDE_DOOFFS;
unsigned path_max = PATH_MAX;
int struct_ttyent_sz = sizeof(struct ttyent);
// ioctl arguments
unsigned struct_ifreq_sz = sizeof(struct ifreq);
unsigned struct_termios_sz = sizeof(struct termios);

View File

@ -383,6 +383,8 @@ extern const int wordexp_wrde_dooffs;
extern unsigned path_max;
extern int struct_ttyent_sz;
struct __sanitizer_wordexp_t {
uptr we_wordc;
char **we_wordv;
@ -412,6 +414,16 @@ struct __sanitizer_ifconf {
} ifc_ifcu;
};
struct __sanitizer__ttyent {
char *ty_name;
char *ty_getty;
char *ty_type;
int ty_status;
char *ty_window;
char *ty_comment;
char *ty_group;
};
# define IOC_NRBITS 8
# define IOC_TYPEBITS 8
# if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)

View File

@ -0,0 +1,60 @@
// RUN: %clangxx -O0 -g %s -o %t
//
// REQUIRES: freebsd, netbsd
#include <assert.h>
#include <stdlib.h>
#include <ttyent.h>
#include <assert.h>
#include <stdlib.h>
#include <ttyent.h>
void test1() {
struct ttyent *typ = getttyent();
assert(typ && typ->ty_name != nullptr);
assert(typ->ty_type != nullptr);
endttyent();
}
void test2() {
struct ttyent *typ = getttynam("console");
assert(typ && typ->ty_name != nullptr);
assert(typ->ty_type != nullptr);
endttyent();
}
void test3() {
if (!setttyent())
exit(1);
struct ttyent *typ = getttyent();
assert(typ && typ->ty_name != nullptr);
assert(typ->ty_type != nullptr);
endttyent();
}
#if defined(__NetBSD__)
void test4() {
if (!setttyentpath(_PATH_TTYS))
exit(1);
struct ttyent *typ = getttyent();
assert(typ && typ->ty_name != nullptr);
assert(typ->ty_type != nullptr);
assert(typ->ty_class != nullptr);
endttyent();
}
#endif
int main(void) {
test1();
test2();
test3();
#if defined(__NetBSD__)
test4();
#endif
return 0;
}

View File

@ -1,70 +0,0 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
#include <stdio.h>
#include <stdlib.h>
#include <ttyent.h>
#define STRING_OR_NULL(x) ((x) ? (x) : "null")
void test1() {
struct ttyent *typ = getttyent();
printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
typ->ty_status, STRING_OR_NULL(typ->ty_window),
STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
endttyent();
}
void test2() {
struct ttyent *typ = getttynam("console");
printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
typ->ty_status, STRING_OR_NULL(typ->ty_window),
STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
endttyent();
}
void test3() {
if (!setttyent())
exit(1);
struct ttyent *typ = getttyent();
printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
typ->ty_status, STRING_OR_NULL(typ->ty_window),
STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
endttyent();
}
void test4() {
if (!setttyentpath(_PATH_TTYS))
exit(1);
struct ttyent *typ = getttyent();
printf("%s %s %s %d %s %s %s\n", STRING_OR_NULL(typ->ty_name),
STRING_OR_NULL(typ->ty_getty), STRING_OR_NULL(typ->ty_type),
typ->ty_status, STRING_OR_NULL(typ->ty_window),
STRING_OR_NULL(typ->ty_comment), STRING_OR_NULL(typ->ty_class));
endttyent();
}
int main(void) {
printf("ttyent\n");
test1();
test2();
test3();
test4();
// CHECK: ttyent
return 0;
}