Shared memory `shmctl`: Permissions denied - linux

I am trying to use shared memory in a process without using sudo.
My minimal example:
fn main() {
const KEY:i32 = 453845;
const SIZE:usize = 1024*1024;
unsafe {
let shmid = libc::shmget(KEY, SIZE, libc::IPC_CREAT);
dbg!(shmid);
dbg!(*libc::__errno_location());
let mut description: MaybeUninit<libc::shmid_ds> = MaybeUninit::uninit();
let result = libc::shmctl(KEY, libc::IPC_STAT, description.as_mut_ptr());
dbg!(description.assume_init_read());
dbg!(result);
dbg!(*libc::__errno_location());
}
}
produces the output:
[shared-memory-allocator/src/lib.rs:561] shmid = 1015817
[shared-memory-allocator/src/lib.rs:565] description.assume_init_read() = shmid_ds {
shm_perm: ipc_perm {
__key: 0,
uid: 0,
gid: 0,
cuid: 0,
cgid: 0,
mode: 0,
__pad1: 0,
__seq: 0,
__pad2: 0,
__unused1: 0,
__unused2: 0,
},
shm_segsz: 0,
shm_atime: 0,
shm_dtime: 0,
shm_ctime: 0,
shm_cpid: 0,
shm_lpid: 0,
shm_nattch: 0,
__unused4: 0,
__unused5: 0,
}
[shared-memory-allocator/src/lib.rs:566] result = -1
[shared-memory-allocator/src/lib.rs:567] *libc::__errno_location() = 22
Which is to note that it errors with error code 22 e.g. Permission Denied.
This seems like a simple use case, but checking https://linux.die.net/man/2/shmctl and https://linux.die.net/man/2/shmget has no description of permissions. Looking at https://www.ibm.com/docs/en/zos/2.1.0?topic=functions-shmget-get-shared-memory-segment it does note you can pass permission bits.
But if I change it to
let permissions = (libc::S_IRGRP | libc::S_IROTH | libc::S_IRUSR | libc::S_IWGRP | libc::S_IWOTH | libc::S_IWUSR) as i32;
let shmid = libc::shmget(KEY, SIZE, libc::IPC_CREAT | permissions);
The result is shmget now fails:
[shared-memory-allocator/src/lib.rs:562] shmid = -1
[shared-memory-allocator/src/lib.rs:563] *libc::__errno_location() = 13

Related

ERC20 Event Listener in Rust Programming

I am trying to program an erc20 event listener using Rust programming language and trying to get events from a particular block to the latest block. But even though I have specified from the block it just gives an output from the latest block, not from the specified block. Below is my code:
use hex_literal::hex;
use std::time;
use web3::{
contract::{Contract, Options},
futures::{future, StreamExt},
types::{FilterBuilder, Address},
};
use std::str::FromStr;
use web3::types::{BlockNumber, U64};
#[tokio::main]
async fn main() -> web3::contract::Result<()> {
let web3 = web3::Web3::new(web3::transports::WebSocket::new("wss:").await?);
let filter = FilterBuilder::default()
// this is BSC: TokenHub
.from_block(BlockNumber::Number(U64::from(15255440)))
.address(vec![Address::from_str("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").unwrap()])
/* .topics(
// this is 'Transfer (index_topic_1 address from, index_topic_2 address to, uint256 value)' event
// use https://emn178.github.io/online-tools/keccak_256.html, and type in 'Transfer(address,address,uint256)'
// it will return result hash as used in next line
Some(vec![hex!("d282f389399565f3671145f5916e51652b60eee8e5c759293a2f5771b8ddfd2e").into()]),
None,
None,
None,
)*/
.build();
let sub = web3.eth_subscribe().subscribe_logs(filter).await?;
sub.for_each(|log| {
println!("{:?}", log);
future::ready(())
}).await;
Ok(())
}
Output is like:
Ok(Log { address: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, topics: [0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000007933790a4f00000099e9001629d9fe7775b800, 0x000000000000000000000000938625591adb4e865b882377e2c965f9f9b85e34],
data: Bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 133, 173, 92, 182, 64, 0]),
block_hash: Some(0xa076bddbfd69560de59c9be11cf5ae6f8782ace08d96c4945f3d15d05e91100f),
block_number: Some(15256705),
transaction_hash:Some(0xdd603b88c60e5b5a1aaebedb53d38df626b72d6ec2a11530cf50a8957082f404),
transaction_index: Some(0),
log_index: Some(0),
transaction_log_index: None,
log_type: None,
removed: Some(false) })
Ok(Log { address: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, topics: [0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000002dfa8a0413255ecca71
3b6d1c1e28e634e021478, 0x000000000000000000000000938625591adb4e865b882377e2c965f9f9b85e34],
data: Bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 76,81, 115, 63, 131, 0, 0]),
block_hash:Some(0xa076bddbfd69560de59c9be11cf5ae6f8782ace08d96c4945f3d15d05e91100f),
block_number: Some(15256705),
transaction_hash:Some(0xcf4b91c9c465e8c2b22126ad580e92988162bf51be7520e5cc6dfe9f878faa06),
transaction_index: Some(1),
log_index: Some(4),
transaction_log_index: None,
log_type: None,
removed: Some(false) })
Ok(Log { address: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2,
topics: [0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000938625591adb4e865b882377e2c965f9f9b85e34, 0x000000000000000000000000007933790a4f00000099e9001629d9fe7775b800],
data: Bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 170, 83, 197, 89, 150, 0, 0]),
block_hash: Some(0xa076bddbfd69560de59c9be11cf5ae6f8782ace08d96c4945f3d15d05e91100f),
block_number: Some(15256705),
transaction_hash:Some(0xd45f5b511cf832b407182751c451c32b27a203d8ab60136f9719cf61523b0e9a),
transaction_index: Some(2),
log_index: Some(9),
transaction_log_index: None,
log_type: None, removed: Some(false) })
Ok(Log { address: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2,
topics: [0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000000000000035b5e5ad9019092c665357240f594e, 0x0000000000000000000000002f8ac927aa94293461c75406e90ec0ccfb2748d9],
data: Bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 90,
119, 187, 148, 242, 21, 156]),
block_hash: Some(0xa076bddbfd69560de59c9be11cf5ae6f8782ace08d96c4945f3d15d05e91100f),
block_number: Some(15256705),
transaction_hash:Some(0xd36df58ffe146202ffb9ef2e29e64380991a674c820bb8a1f6a776b9468baa86),
transaction_index: Some(3),
log_index: Some(12),
transaction_log_index: None,
log_type: None,
removed: Some(false) })
I got to the conclusion that the above code gives the output of the event that will happen. So when we add from_block: 15255440, the event has already happened. And in that particular block, no other event is going to happen. So you will get the output from the latest block.
To test this in code add this:
let filter = FilterBuilder::default()
// this is BSC: TokenHub
.from_block(BlockNumber::Number(U64::from(15257125)))
.to_block(BlockNumber::Number(U64::from(15257130)))
.address(vec![Address::from_str("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").unwrap()])
.build();
Keep in mind to replace 15257125(i.e from_block) and 15257130(i.e. to_block) with the future block which has not been mined yet. And when that block will be mined you will get events between that two blocks.

Using golang to create a new child process with syscall.CLONE_NEWUSER but why at the new usernamespace the uid is nobody?

exe := exec.Command("/proc/self/exe","init")
exe.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS|syscall.CLONE_NEWNS|syscall.CLONE_NEWUSER|syscall.CLONE_NEWPID|syscall.CLONE_NEWIPC|syscall.CLONE_NEWNET,
//mapping the uid and gid I can figure out the mapping rules????
UidMappings: []syscall.SysProcIDMap{
{
ContainerID: 0,
HostID: 1000000,
Size: 65536,
},
},
GidMappings: []syscall.SysProcIDMap{
{
ContainerID: 0,
HostID: 100000,
Size: 65536,
},
},
}
when I run with exe.Start() get the result at terminal is "nobody#xx:/home/xx$" .
I read the code of runc ,likewise,runc use the same way to implement usernamespace's isolation,but set correctly uid with 'root'. what's wrong with me?
There is system info of my new process,getting from another bash.
root#xx:/home/xx# cat /proc/159624/uid_map
0 1000000 65536
root#xx:/home/xx# cat /etc/subuid
xx:100000:65536
os: ubuntu20.04
go version:1.18.3 linux/amd64

Sharp fails on resize with zsh: killed

I have a small node script to resize images for a website:
const sharp = require('sharp')
const fsp = require('fs/promises')
const path = require('path')
const FILES = [
'/home/xx/68/ea/68ea8c14c2b655c50cbc560b9f3a5af620882670.jpeg',
'/home/xx/4e/7f/4e7f94103480d8ff231b17310c598470dc10489c.jpeg',
]
const SIZES = [ 300, 500, 800, 1024, 2048 ]
const FORMATS = [ 'jpeg' ]
const dir = '/home/xx/media/temp/'
async function generatePreviews(pathName, name) {
const image = sharp(pathName)
const metadatas = await image.metadata()
console.log('format:', metadatas.format)
console.log('width:', metadatas.width)
console.log('height:', metadatas.height)
console.log('weight:', await fsp.stat(pathName))
for (const size of SIZES) {
for (const format of FORMATS) {
console.log('start create preview', name, format, size)
try {
await image.clone()
.resize(size, size, {fit: 'inside'})
.toFile(path.join(dir, `preview_${name}_${size}.${format}`))
console.log('Preview created', name, format, size)
} catch (e) {
console.log('An error occured')
console.log(e)
}
}
}
}
async function testPreviews() {
console.log('start generating previews')
for (let i = 0; i < FILES.length; i++) {
await generatePreviews(FILES[i], i)
}
console.log('All previews generated')
}
testPreviews()
It works perfectly on my desktop computer (old i5 760 from 2010), but on my server, it fails almost silently when generating the largest previews for the largest file…
Here is the output on the server:
% node ./src/scripts/test_sharp.js
start generating previews
format: jpeg
width: 683
height: 1024
weight: Stats {
dev: 51713,
mode: 33188,
nlink: 1,
uid: 1001,
gid: 1001,
rdev: 0,
blksize: 4096,
ino: 658937,
size: 473209,
blocks: 928,
atimeMs: 1654021875500.3074,
mtimeMs: 1467568028343.9807,
ctimeMs: 1645954831869.6965,
birthtimeMs: 1645954825541.6052,
atime: 2022-05-31T18:31:15.500Z,
mtime: 2016-07-03T17:47:08.344Z,
ctime: 2022-02-27T09:40:31.870Z,
birthtime: 2022-02-27T09:40:25.542Z
}
start create preview 0 jpeg 300
Preview created 0 jpeg 300
start create preview 0 jpeg 500
Preview created 0 jpeg 500
start create preview 0 jpeg 800
Preview created 0 jpeg 800
start create preview 0 jpeg 1024
Preview created 0 jpeg 1024
start create preview 0 jpeg 2048
Preview created 0 jpeg 2048
format: jpeg
width: 3840
height: 5760
weight: Stats {
dev: 51713,
mode: 33188,
nlink: 1,
uid: 1001,
gid: 1001,
rdev: 0,
blksize: 4096,
ino: 658752,
size: 2272667,
blocks: 4440,
atimeMs: 1654021876468.3223,
mtimeMs: 1468007124640.3523,
ctimeMs: 1645954169924.1448,
birthtimeMs: 1645954151475.8787,
atime: 2022-05-31T18:31:16.468Z,
mtime: 2016-07-08T19:45:24.640Z,
ctime: 2022-02-27T09:29:29.924Z,
birthtime: 2022-02-27T09:29:11.476Z
}
start create preview 1 jpeg 300
Preview created 1 jpeg 300
start create preview 1 jpeg 500
Preview created 1 jpeg 500
start create preview 1 jpeg 800
zsh: killed node ./src/scripts/test_sharp.js
It fails at 800px side preview generation for the largest file (5760 x 3840px).
The catch block doesn't trigger…
Server is a 1 CPU VPS with 1GB of RAM (hosted at gandi.net).
% node --version
v16.15.0
% yarn list --pattern sharp 1 Jun 04:06:40
yarn list v1.22.18
└─ sharp#0.30.6
Done in 1.49s.
Any help would be appreciated :)

JOINT JS orhtogonal links not working properly

I have set my links to be orthogonal in JOINTJS , but still i can see slanting lines. How can i rectify this ?
Image
check the right end which is not vertical but slanting . my code is as follows
> defaultLink: new joint.dia.Link({
> router: { name: 'manhattan' },
> connection : {name: 'orthogonal'},
> attrs: {
> '.marker-target': { d: 'M 10 0 L 0 5 L 10 10 z', fill: '#fff', stroke: '#000' },
> '.link-tools .tool-remove circle, .marker-vertex': { r: 8 },
> '.connection': {
> stroke: '#000', 'stroke-width': 1
> //filter: { name: 'dropShadow', args: { dx: 1, dy: 1, blur: 2 } }
> }
> }
> })

No UiSlider remove decimal?

How to remove decimals digit from linked output
I am using this code
$("#slider_01").noUiSlider({
start: [2000, 24000],
connect: true,
step: 0.01,
range: {
'min': 0,
'max': 28500
},
format: wNumb({
decimals: false,
thousand: ',',
prefix: '$ ',
})
});
$('#slider_01').Link('lower').to($('#value-lower_1'));
$('#slider_01').Link('upper').to($('#value-upper_1'));
I didn't have access to the wNumb library in the environment I was working with.
Had a look under the hood in the library and this also works:
$("#slider_01").noUiSlider({
...
format: {
to: (v) => parseFloat(v).toFixed(0),
from: (v) => parseFloat(v).toFixed(0)
}
});
Decimals decimals: false is invalid, use decimals: 0. Also, you are setting formatting for the .val() method. Use it like this:
$('#slider_01').Link('lower').to($('#value-lower_1'), null, wNumb({
decimals: 0,
thousand: ',',
prefix: '$ ',
}));
Change the step from 0.01 to 1.
I know it's a very old question, but I did not want to include another library Wnumb just to remove the decimal from one place. Here is my solution without using the wnumb.
var slider = document.getElementById('prcsldr');
noUiSlider.create(slider, {
start: [10000],
range: {
min: 1000,
max: 50000
},
step: 1000,
format:{
to: (v) => v | 0,
from: (v) => v | 0
}
});

Resources