nwnss: restore unicode loader userspace boundary

This commit is contained in:
OpenAI
2026-06-19 17:19:06 +00:00
committed by Mario Fetka
parent d3c050b0a3
commit 4111bbdc38
4 changed files with 1744 additions and 416 deletions

View File

@@ -0,0 +1,42 @@
#ifndef NSS_UNICODE_USERSPACE_H
#define NSS_UNICODE_USERSPACE_H
#include <stddef.h>
#include <stdio.h>
#include <fcntl.h>
#include <public/zOmni.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#ifndef MPK_SLEEP_OK
#define MPK_SLEEP_OK 0
#endif
struct file {
FILE *stream;
long f_pos;
};
void mpkEnter(void);
void mpkExit(void);
void *mpkPageAlloc(unsigned int bytes, int flags);
void mpkPageFree(void *ptr);
void *kMutexAlloc(const char *name);
void kMutexFree(void *lock);
void kMutexLock(void *lock);
void kMutexUnlock(void *lock);
struct file *kFileOpen(const char *path, int flags, int mode);
int kFileRead(struct file *filep, void *buf, unsigned int count);
void klseek(struct file *filep, unsigned int pos, int whence);
int filp_close(struct file *filep, void *unused);
int printk(const char *fmt, ...);
LONG OSGetCodePage(void);
#ifndef IS_ERR
#define IS_ERR(ptr) ((ptr) == NULL)
#endif
#endif /* NSS_UNICODE_USERSPACE_H */

View File

@@ -309,6 +309,7 @@ add_library(nwnss SHARED
nss/lib/setErrno.c
nss/msg/slab.c
nsslnxlib/unilib.c
nsslnxlib/unilibUserspace.c
lsa/lsaComn.c
lsa/lsaErr.c
lsa/lsaSuperXattr.c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
/****************************************************************************
|
| Userspace runtime boundary for the NSS Unicode rule-table loader.
|
| Keep NSS Unicode semantics in unilib.c. This file supplies the process
| runtime used by libnwnss: table discovery, file reads, memory allocation,
| lightweight locking hooks, and host-codepage selection.
+-------------------------------------------------------------------------*/
#include <errno.h>
#include <stddef.h>
#include <nsslnxlib/nssunilib.h>
#include <internal/nssUnicodeUserspace.h>
#include <nssConfig.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef NSS_DEFAULT_CODEPAGE
#define NSS_DEFAULT_CODEPAGE 850
#endif
#ifndef NSS_UNITABLE_DIRS
#define NSS_UNITABLE_DIRS ""
#endif
extern char *getenv(const char *name);
extern long strtol(const char *nptr, char **endptr, int base);
void mpkEnter(void)
{
}
void mpkExit(void)
{
}
void *mpkPageAlloc(unsigned int bytes, int flags)
{
(void)flags;
return calloc(1, bytes);
}
void mpkPageFree(void *ptr)
{
free(ptr);
}
void *kMutexAlloc(const char *name)
{
(void)name;
return (void *)1;
}
void kMutexFree(void *lock)
{
(void)lock;
}
void kMutexLock(void *lock)
{
(void)lock;
}
void kMutexUnlock(void *lock)
{
(void)lock;
}
static const char *basename_of(const char *path)
{
const char *slash;
if (!path)
return "";
slash = strrchr(path, '/');
return slash ? slash + 1 : path;
}
static FILE *try_open_path(const char *dir, const char *name)
{
char path[1024];
if (!dir || !*dir)
return NULL;
snprintf(path, sizeof(path), "%s/%s", dir, name);
return fopen(path, "rb");
}
static FILE *open_unicode_table_stream(const char *path)
{
const char *env_dir = getenv("NSS_UNITABLE_DIR");
const char *dirs = NSS_UNITABLE_DIRS;
const char *name = basename_of(path);
char dirs_copy[2048];
char *save = NULL;
char *dir;
FILE *stream;
stream = fopen(path, "rb");
if (stream)
return stream;
stream = try_open_path(env_dir, name);
if (stream)
return stream;
if (dirs && *dirs) {
snprintf(dirs_copy, sizeof(dirs_copy), "%s", dirs);
for (dir = strtok_r(dirs_copy, ":", &save); dir; dir = strtok_r(NULL, ":", &save)) {
stream = try_open_path(dir, name);
if (stream)
return stream;
}
}
return fopen(name, "rb");
}
struct file *kFileOpen(const char *path, int flags, int mode)
{
struct file *filep;
FILE *stream;
(void)flags;
(void)mode;
stream = open_unicode_table_stream(path);
if (!stream)
return NULL;
filep = calloc(1, sizeof(*filep));
if (!filep) {
fclose(stream);
return NULL;
}
filep->stream = stream;
filep->f_pos = 0;
return filep;
}
int kFileRead(struct file *filep, void *buf, unsigned int count)
{
size_t got;
if (!filep || !filep->stream)
return -EINVAL;
if (fseek(filep->stream, filep->f_pos, SEEK_SET) != 0)
return -errno;
got = fread(buf, 1, count, filep->stream);
filep->f_pos += (long)got;
if (got != count && ferror(filep->stream))
return -EIO;
return (int)got;
}
void klseek(struct file *filep, unsigned int pos, int whence)
{
if (!filep)
return;
if (whence == SEEK_CUR)
filep->f_pos += (long)pos;
else if (whence == SEEK_END && filep->stream) {
if (fseek(filep->stream, 0, SEEK_END) == 0)
filep->f_pos = ftell(filep->stream) + (long)pos;
} else
filep->f_pos = (long)pos;
}
int filp_close(struct file *filep, void *unused)
{
int rc = 0;
(void)unused;
if (!filep)
return 0;
if (filep->stream)
rc = fclose(filep->stream);
free(filep);
return rc;
}
int printk(const char *fmt, ...)
{
va_list ap;
int rc;
va_start(ap, fmt);
rc = vfprintf(stderr, fmt, ap);
va_end(ap);
return rc;
}
static int parse_int_env(const char *name, int fallback)
{
const char *value = getenv(name);
char *end = NULL;
long parsed;
if (!value || !*value)
return fallback;
parsed = strtol(value, &end, 10);
if (!end || *end || parsed <= 0 || parsed > 65535)
return fallback;
return (int)parsed;
}
LONG OSGetCodePage(void)
{
return parse_int_env("NSS_CODEPAGE", NSS_DEFAULT_CODEPAGE);
}